温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何使用OpenZeppelin在RSK上进行ERC20开发

发布时间:2021-08-30 09:56:25 来源:亿速云 阅读:167 作者:chen 栏目:互联网科技

本篇内容介绍了“如何使用OpenZeppelin在RSK上进行ERC20开发”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

创建合约

我们需要做的第一件事就是知道如何使用Truffle

当我们这样做

$ truffle init

在一个空文件夹中,除了创建配置文件外,我们还为项目和迁移合约创建了文件夹,以记录对同一合约的更改。

合约的.sol代码文件位于

~/Truffle/contracts

迁移脚本在

~/Truffle/migrations

已编译的合约在

~/Truffle/build

测试合约在

~/Truffle/test

我们现在只处理前两个文件夹。

在Truffle文件夹中,我们从OpenZeppelin导入库

$ npm install -E openzeppelin-solidity

这些库不仅会安装我们代币token的主要类库,还会安装所有权相关,安全数学运算和许多其他设施的库。值得一提的是,这些库已经过审核以实现高标准的安全性,因此依赖于它们的合约在正确使用时不易受到黑客攻击。

我们的库将安装在

~/Truffle/node_modules/openzeppelin-solidity/contracts

之后,我们可以将库ABCD.sol导入到我们的合约中,如下所示:

import 'zeppelin-solidity/contracts/token/ERC20/ABCD.sol';

要创建我们的ERC20代币,我们将从该存储库导入2个库:StandardToken.sol,它具有代币的主要功能,并且已经更多地导入了一堆库,例如SafeMath.solOwnable.sol,这些允许我们设置所有者对合约中的功能控制。

要继承库属性和函数,我们只需使用“is”关键字以这种方式将合约定义为StandardTokenOwnable

contract CoinFabrikToken is StandardToken, Ownable { }

之后,我们拥有这些库和导入库中的所有功能。

接下来,我们将代币的名称定义为CoinFabrik,这是它的符号,18个小数位,用于代币的精度(以太坊类网络中的标准,使我们有可能使用web3的以太转换功能)并将代币的初始供应量设置为1000,像这样:

string public name = 'CoinFabrik';
string public symbol = 'CF';
uint8 public decimals = 18;
uint public INITIAL_SUPPLY = 1000;

我们还将创建另一个字符串,一个与代币功能无关的非公共变量,以显示Ownable库属性的用法,该属性仅允许创建者与某些指定的函数进行交互。我们稍后会看到。

已经定义了我们的参数,现在是时候通过构造函数将它们分配给Token变量了。到目前为止,构造函数被定义为一个与智能合约同名的函数,但是从现在开始,将会有一个名为constructor()的函数,它将替换旧方法。如果你像以前一样调用构造函数,Solidity编译器将发出警告。

INITIAL_SUPPLY乘以小数精度的次方将分配给BasicToken合约的totalSupply_

totalSupply_ = INITIAL_SUPPLY * (10**uint(decimals));

并将它们存入创作者的帐户:

balancesb [msg.sender] = totalSupply_;

有了这个,我们就可以使用一个简单而标准的代币,但正如我们所说,我们将使用Ownable合约添加一些功能。首先,我们将定义一些函数:一个修改我们的非公共变量的状态,但只有你拥有权限,而另一个函数返回字符串的消息。定义如下:

function setON(string _n) public onlyOwner returns (bool) {
    Owner = _n;
    return true;
  }
 
function getON() public view returns (string) {
    return Owner;
  }

两者都是公开的,所以任何人都可以尝试调用他们,但对于第一个,只有所有者的地址不会导致恢复。如果你是所有者并且调用了函数,则字符串将保存在我们的变量Owner(带有大写字母)中,并且它还将返回一个我们可以在交易中检查的true值。

由于Owner变量不是公共的并且没有Getter,我们需要一个函数来返回变量的值而不改变区块链的状态。这是第二个功能。

我们还将创建一个回调函数,如果有人错误地调用我们的合约,则会发出事件:

function () public payable {
    if (msg.value > 0) {
      emit Yes('Thanks for donating SBTC! :)');
    } else {
      emit No('Error 404: Function not found :P');
    }
}

最后,我们在合约中添加了一个可销毁的功能,其中所有者是唯一可以执行它的人。

我们的简单代币已经完成。所有代码应该是一样的:

pragma solidity ^0.4.17;
 
import 'zeppelin-solidity/contracts/token/ERC20/StandardToken.sol';
import "zeppelin-solidity/contracts/ownership/Ownable.sol";
 
contract CoinFabrikToken is StandardToken, Ownable {
  string public name = 'CoinFabrik';
  string public symbol = 'CF';
  uint8 public decimals = 18;
  uint public INITIAL_SUPPLY = 1000;
 
  string Owner;
 
  event Yes(string);
  event No(string);
 
  constructor() public {
    totalSupply_ = INITIAL_SUPPLY * (10**uint(decimals));
    balances[msg.sender] = totalSupply_;
  }
 
  function setON(string _n) public onlyOwner returns (bool) {
    Owner = _n;
    return true;
  }
 
  function getON() public view returns (string) {
    return Owner;
  }
 
  function () public payable {
    if (msg.value > 0) {
      emit Yes('Thanks for donating SBTC! :)');
    } else {
      emit No('Error 404: Function not found :P');
    }
  }
 
  function destroy() public onlyOwner {
    selfdestruct(owner);
  }
 
}

创建迁移

对于每个合约,我们需要告诉Truffle哪个合约是我们想要部署的合约以及我们可以在哪里找到合约。这是通过/Truffle/migrations文件夹中的迁移文件完成的。

迁移脚本02_deploy_token.js应如下所示

var CoinFabrikToken = artifacts.require("./CoinFabrikToken.sol");
module.exports = function(deployer) {
  deployer.deploy(CoinFabrikToken);
};

我们已配置Truffle,我们的节点已同步,我们的合约已经编写并且我们的迁移已配置,完成部署就是个时间问题。

部署

如果我们之前停止了我们的节点,我们将恢复在线状态,然后我们将与Truffle连接:

$ sudo service rsk start
$ cd ~/Truffle/ && truffle console --network rsk

之后编译合约:

truffle(rsk)> compile --all

不应该对我们的合约有任何错误或警告。然后我们转移合约:

truffle(rsk)> migrate --reset

为了节约时间,我们可以在一行中执行两个命令

truffle(rsk)> migrate --all --reset

将首先部署迁移合约。Truffle为我们提供了每个操作的交易哈希,因此我们可以稍后检查详细信息或日志。这是我收到的完整输出

truffle(rsk)> migrate --all --reset
Compiling ./contracts/CoinFabrikToken.sol...
Compiling ./contracts/Migrations.sol...
Compiling zeppelin-solidity/contracts/math/SafeMath.sol...
Compiling zeppelin-solidity/contracts/ownership/Ownable.sol...
Compiling zeppelin-solidity/contracts/token/ERC20/BasicToken.sol...
Compiling zeppelin-solidity/contracts/token/ERC20/ERC20.sol...
Compiling zeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol...
Compiling zeppelin-solidity/contracts/token/ERC20/StandardToken.sol...
Writing artifacts to ./build/contracts
 
Using network 'rsk'.
 
Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0xf00d4ecf2b5752022384f7609fe991aa72dda00a0167a974e8c69864844ae270
  Migrations: 0x1dc2550023bc8858a7e5521292356a3d42cdcbe9
Saving successful migration to network...
  ... 0x3e759e8ff8a7b8e47a441481fa5573ccf502b83f3d591ad3047e622af0f9169e
Saving artifacts...
Running migration: 2_deploy_token.js
  Deploying CoinFabrikToken...
  ... 0x300c8bb1e434e2aa4b13dcc76087d42fcbe0cb953989ca53a336c59298716433
  CoinFabrikToken: 0xc341678c01bcffa4f7362b2fceb23fbfd33373ea
Saving successful migration to network...
  ... 0x71771f7ee5d4e251e386979122bdda8728fa519d95a054572751bb10d40eb8c5
Saving artifacts...

如果我们检查交易,我们可以计算所有部署过程的gas成本。在我这里的情况,它是2340788gas(277462+42008+1994310+27008)。

因此将其更改为真实的SBTC,我们得到2340788*183000000/10^18=0,000428364 SBTC。在撰写本文时,这大约是4美元左右。

我们的合约现在部署在0xc341678c01bcffa4f7362b2fceb23fbfd33373ea。

恭喜!

与合约互动

通过Truffle迁移给出的地址,以及合约的ABI,我们创建了一个实例,因此简化语法更容易处理函数。为此,在我们部署之后,我们写了

truffle(rsk)> var cfToken = web3.eth.contract(CoinFabrikToken.abi).at(CoinFabrikToken.address)

如果合约已经部署,并且知道它的地址和ABI,我们就可以做到

truffle(rsk)> var cfToken = web3.eth.contract(‘Contract_ABI’).at(‘Contract_ADDRESS’)

其中Contract_ABI是简化为一行ABI,Contract_ADDRESS不需要解释。

我之前创建了2个帐户,现在为方便起见,我们将它们重命名:

truffle(rsk)> var acc0 = web3.eth.accounts[0]
truffle(rsk)> var acc1 = web3.eth.accounts[1]

acc0是部署合约的人。Acc0被添加到truffle.jsnode.conf配置文件中。

所有权控制

我们将首先使用我们讨论过的库来测试合约的所有权功能。

如果我们从任何帐户调用getON函数,只要它是公开的并且没有任何所有权问题,我们就会得到:

truffle(rsk)> cfToken.getON()
''

现在,setON函数具有所有权属性。任何来自其他帐户的交易都将被驳回。例如,我们看到,试图用我的名字从acc1签订合约不会改变它的价值。

truffle(rsk)> cfToken.setON('Andres Bachfischer', {from: acc1})
0x5f115190b60238240bedf36d1c5bb69a443a0f8ee971b0fc40fe5ca9c727d47c

如何使用OpenZeppelin在RSK上进行ERC20开发

使用交易的哈希,我们看到返回的值为false,并且函数未正确执行。再次调用getON函数,我们看到变量没有改变它的值。

现在签署相同的交易但是从所有者的帐户acc0,我们得到状态'0x01'并且该功能正确执行。

truffle(rsk)> cfToken.setON('Andres Bachfischer', {from: acc0})
0x0c894fa7e5369573fb14addeaed4cd9d5b6cd1425cb4eeeae16cb4e1fa8e0364

如何使用OpenZeppelin在RSK上进行ERC20开发

再次调用函数getON,我们看到所有权库按照我们希望的那样工作。

truffle(rsk)> cfToken.getON()

如何使用OpenZeppelin在RSK上进行ERC20开发

Ownable.sol还具有允许我们将合约所有者更改为其他地址的功能。我们不会用它。然而,它的用法如下:

truffle(rsk)> cfToken.transferOwnership(acc1, {from: acc0})

有了这个,acc1将成为合约的新所有者。

让我们转到代币。

代币操作

我们要做的第一件事是检查在创建合约时是否正确分配了代币的余额。

我们检查每个帐户的余额如下:

web3.fromWei(cfToken.balanceOf(acc0).toString(10)) // = ‘1000’
web3.fromWei(cfToken.balanceOf(acc1).toString(10)) // = ‘0’

因此,我们可以看到所有代币都已正确分配到我们的初始帐户。

我们要做的第一笔交易是将一些代币转移到第二个帐户acc1,进行三次。

为第一笔交易这样做:

truffle(rsk)> cfToken.transfer(acc1, web3.toWei(88.8), {from: acc0})
0xd45437b777f1430e7cec57bd80b261ce8f87bf8a3f9a113fecd20563403c4d9c

如何使用OpenZeppelin在RSK上进行ERC20开发

truffle(rsk)> web3.fromWei(cfToken.balanceOf(acc0).toString(10)) // = '733.6'
truffle(rsk)> web3.fromWei(cfToken.balanceOf(acc1).toString(10)) // = '266.4'

如何使用OpenZeppelin在RSK上进行ERC20开发

我们看到从我们的部署帐户中获取的代币与在acc1中收到的代币数量相同。

使用StandardToken合约,我们还获得了代表某个帐户(在本例中为acc1)支出代币的权限。如果我们想在获得批准之前执行此操作,则交易将失败(状态为“0x00”)

truffle(rsk)> cfToken.transferFrom(acc1, acc0, web3.toWei(5), {from: acc0})
0x5cee7cf60849283a0088d71483a606ba2101b500e13f972abada4f75781596bf

如何使用OpenZeppelin在RSK上进行ERC20开发

检查后,acc0不允许从acc1发送:

truffle(rsk)> web3.fromWei(cfToken.allowance(acc1, acc0, {from: acc0}).toString(10)) // = '0'

我们授权acc0acc1的交易中以acc1的名义花费10个代币:

truffle(rsk)> cfToken.approve(acc0, web3.toWei(10), {from: acc1})
0x6e1a202f4ca7f43dfb28034952d54a572993b986a55857790aa51854afbc1fb4

如何使用OpenZeppelin在RSK上进行ERC20开发

在输出日志中,我们看到函数已成功完成,并且日志显示允许acc0用于支出的金额。检查allowance:

truffle(rsk)> web3.fromWei(cfToken.allowance(acc1, acc0, {from: acc0}).toString(10)) // = '10'

如何使用OpenZeppelin在RSK上进行ERC20开发

现在,如果我们再次执行支出交易:

truffle(rsk)> cfToken.transferFrom(acc1, acc0, web3.toWei(5), {from: acc0})
0x41f750eabb6e0d3ab576aac0333b0d337ca61808aae1eeafa9d8e2a0b81b979b

我们得到状态为“0x01”的成功交易。

如何使用OpenZeppelin在RSK上进行ERC20开发

再检查一下余额:

truffle(rsk)> web3.fromWei(cfToken.balanceOf(acc0).toString(10)) // = '738.6'
truffle(rsk)> web3.fromWei(cfToken.balanceOf(acc1).toString(10)) // = '261.4'

如何使用OpenZeppelin在RSK上进行ERC20开发

最后,如果我们签署一个调用不可用函数的事务,我们将调用我们的回退函数。 签署一个像这样的交易:

truffle(rsk)> web3.eth.sendTransaction({from: acc0, to: cfToken.address})
0x4106a287fc60669bf9682a73ec4c457b094c086ec7408a5dea95d200688c4ee9

如何使用OpenZeppelin在RSK上进行ERC20开发

将返回一个日志,其数据表示字符串Error 404:Function not found:P(十六进制:'0x00 ... 00204572726f72203430343a2046756e6374696f6e206e6f7420666f756e64203a50')。

我们的最后一个功能,即我们不会因为显而易见的原因而执行,就是销毁功能。我们需要合约不被销毁才能显示交易。要调用,所有者应该这样做:

truffle(rsk)> cfToken.destroy({from: acc0})

结论

在演练的第二部分中,我展示了在RSK网络中开发简单智能合约的示例。 我们已经看过:

  • 从OpenZeppelin套件导入库和合约,

  • 使用这些库创建一个简单的代币,

  • 配置Truffle的迁移过程,

  • 将我们的合约部署到RSK主网络,

  • 通过不同的账户与合约互动,

  • 检查块的日志以获取有关事务的反馈。

正如我们所看到的,RSK网络用于Solidity Smart Contracts部署和交互的用法几乎与以太坊节点中的相同。当然,这仍然是一个测试网络,预计会出现问题和错误,主要是在节点中,但RSK Labs团队在他们出现时尽可能快地解决它们。随着时间的推移,将实现稳健性。

“如何使用OpenZeppelin在RSK上进行ERC20开发”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI