在本文中,我们将讨论通过RSK网络部署和交互Smart-Contracts智能合约。我们的合约将是一个基于OpenZeppelin库的ERC20代币,我们将把它直接部署到Mainnet中。

创建合约

我们需要做的第一件事就是知道如何使用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/contractsUsing network 'rsk'.Running migration: 1_initial_migration.jsDeploying Migrations...... 0xf00d4ecf2b5752022384f7609fe991aa72dda00a0167a974e8c69864844ae270Migrations: 0x1dc2550023bc8858a7e5521292356a3d42cdcbe9
Saving successful migration to network...... 0x3e759e8ff8a7b8e47a441481fa5573ccf502b83f3d591ad3047e622af0f9169e
Saving artifacts...
Running migration: 2_deploy_token.jsDeploying CoinFabrikToken...... 0x300c8bb1e434e2aa4b13dcc76087d42fcbe0cb953989ca53a336c59298716433CoinFabrikToken: 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

image

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

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

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

image

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

truffle(rsk)> cfToken.getON()

image

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

image

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

image

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

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

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

image

检查后,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

image

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

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

image

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

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

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

image

再检查一下余额:

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

image

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

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

image

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

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

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

结论

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

  • 从OpenZeppelin套件导入库和合约,
  • 使用这些库创建一个简单的代币,
  • 配置Truffle的迁移过程,
  • 将我们的合约部署到RSK主网络,
  • 通过不同的账户与合约互动,
  • 检查块的日志以获取有关事务的反馈。

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

======================================================================

分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:

  • java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
  • python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
  • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。
  • 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
  • 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
  • EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
  • java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
  • php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
  • tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。

汇智网原创翻译,转载请标明出处。这里是原文使用OpenZeppelin在RSK上进行ERC20代币开发

用OpenZeppelin在RSK上进行以太坊ERC20代币开发相关推荐

  1. erc20钱包下载_以太坊ERC20代币数据集【1000+】

    Erc20Tokens数据集包含超过1000种主流的以太坊ERC20代币的描述数据清单和图标,可用于钱包等区块链应用的开发,支持使用Java.Python.Php.NodeJs.C#等各种开发语言查询 ...

  2. 以太坊ERC20代币合约案例

    一.ERC20代币合约与web3调用 ERC20代币合约在小白看来觉得很高大上,但其实就是一个代币的定义标准,方便其他dapp统一调用各种代币的方法.如图: 二.ERC20合约标准 [官方链接] co ...

  3. 使用OpenZeppelin在RSK上进行ERC20代币开发

    在本文中,我们将讨论通过RSK网络部署和交互Smart-Contracts智能合约.我们的合约将是一个基于OpenZeppelin库的ERC20代币,我们将把它直接部署到Mainnet中. 创建合约 ...

  4. 基于以太坊实现代币|基于以太坊实现你自己的加密货币

    文章内容主要来自于 https://www.ethereum.org/token. 笔者没有过英语4级,翻译的不好请见谅 _ 代币 我们将创建一个数字令牌(digital token).以太坊生态系统 ...

  5. 在MacOS上构建以太坊开发环境

    以太坊是流行的区块链去中心化平台.作为本文的一部分,你将了解如何在MacOS平台上设置以太坊. 首先需要对区块链和以太坊有基本理解,即什么是以太坊之类的? 工具集 以太坊开发生态系统包括以下工具列表. ...

  6. 如何在Ubuntu Linux上开采以太坊?

    截至最近,加密货币热潮席卷整个互联网社区.人们发现,不需要一个价值数千美元的矿机就可以从中赚钱的加密货币.商店里显卡短缺,淘金热已经席卷了矿商.如果您有一张超过2GB的VRAM,您也可以尝试挖掘.让我 ...

  7. 以太坊区块链Ethereum开发资料汇总

    2019独角兽企业重金招聘Python工程师标准>>> 基本概念介绍 :国内介绍区块链比较详细的资料 终于把区块链的技术与应用讲清楚了 http://business.sohu.co ...

  8. truffle (ETH以太坊智能合约集成开发工具) 入门教程

    truffle (ETH以太坊智能合约集成开发工具) 入门教程 前言 在你了解区块链开发之前,你有必要了解区块链的一些基础知识,什么是DApp,DApp与传统app的区别, 什么是以太坊,以太坊中的智 ...

  9. 在以太坊开发自己的ERC-20代币及如何ICO

    今天我将向你展示如何在以太坊区块链上开发你自己的加密货币并将其出售!我将向你展示如何使用以太坊智能合约逐步创建自己的ERC-20代币和众筹销售,如何测试智能合约,如何将智能合约部署到以太坊区块链,以及 ...

最新文章

  1. PAT(甲级)2019年春季考试 7-3 Telefraud Detection
  2. OC基础-关于构造方法
  3. 《你的灯亮着吗》读书笔记1
  4. 茫茫内存,我该如何用 windbg 找到你 ?
  5. java定义一个course类,java集合,定义两个类,学生Student和课程Course,课程被学生选修,请在课程类中提供以下功能:...
  6. MySQL Statement Cancellation Timer] but has failed to stop it.
  7. 哪本书是对程序员最有影响(stackoverflow)
  8. (8)FPGA时钟设计(第2天)
  9. 程序员月薪2万怎么了?8千又怎么了?
  10. 【Hive】Hive分区表
  11. customErrors与错误页面
  12. 第25版 OpenStack Yoga 已发布:稳定性与创新并重
  13. 网页星号点号密码查看最简方法
  14. 中国乡镇企业会计杂志中国乡镇企业会计杂志社中国乡镇企业会计编辑部2022年第12期目录
  15. 新版HyperMesh的Assemblies中调出下拉菜单查看Component(装配关系模型树)
  16. Linux学习过程感悟
  17. excel 作图-- 主次纵坐标轴 横坐标名称太长
  18. vbs 产生随机数
  19. HarmonyOS系统架构
  20. 从角雷达到前向雷达,中国厂商如何加速突围?

热门文章

  1. 位运算判断一个数是奇数还是偶数
  2. 计算机没有网络设备器,没有网络适配器怎么解决 电脑没有网络适配器的解决方法...
  3. 三角形判断(直角,等边,一般)
  4. 从山西最年轻首富到中国第一败家子,李兆会的人生究竟有多魔幻?
  5. BT下载工具——bitstormlite
  6. are exo exo是什么歌 we_EXO we are one
  7. sendmessage获取usb摄像机_尽职尽责 家庭哨兵——360摄像机云台变焦版再体验
  8. 利用pipenv和pyenv管理多个相互独立的Python虚拟开发环境
  9. android操作系统的介绍
  10. vulnhub:DC1靶机