您好,登錄后才能下訂單哦!
本篇內容介紹了“如何使用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.sol
;Ownable.sol
,這些允許我們設置所有者對合約中的功能控制。
要繼承庫屬性和函數,我們只需使用“is”關鍵字以這種方式將合約定義為StandardToken
和Ownable
:
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.js
和node.conf
配置文件中。
我們將首先使用我們討論過的庫來測試合約的所有權功能。
如果我們從任何帳戶調用getON
函數,只要它是公開的并且沒有任何所有權問題,我們就會得到:
truffle(rsk)> cfToken.getON() ''
現在,setON函數具有所有權屬性。任何來自其他帳戶的交易都將被駁回。例如,我們看到,試圖用我的名字從acc1
簽訂合約不會改變它的價值。
truffle(rsk)> cfToken.setON('Andres Bachfischer', {from: acc1}) 0x5f115190b60238240bedf36d1c5bb69a443a0f8ee971b0fc40fe5ca9c727d47c
使用交易的哈希,我們看到返回的值為false,并且函數未正確執行。再次調用getON函數,我們看到變量沒有改變它的值。
現在簽署相同的交易但是從所有者的帳戶acc0,我們得到狀態'0x01'并且該功能正確執行。
truffle(rsk)> cfToken.setON('Andres Bachfischer', {from: acc0}) 0x0c894fa7e5369573fb14addeaed4cd9d5b6cd1425cb4eeeae16cb4e1fa8e0364
再次調用函數getON
,我們看到所有權庫按照我們希望的那樣工作。
truffle(rsk)> cfToken.getON()
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
truffle(rsk)> web3.fromWei(cfToken.balanceOf(acc0).toString(10)) // = '733.6' truffle(rsk)> web3.fromWei(cfToken.balanceOf(acc1).toString(10)) // = '266.4'
我們看到從我們的部署帳戶中獲取的代幣與在acc1中收到的代幣數量相同。
使用StandardToken
合約,我們還獲得了代表某個帳戶(在本例中為acc1)支出代幣的權限。如果我們想在獲得批準之前執行此操作,則交易將失敗(狀態為“0x00”)
truffle(rsk)> cfToken.transferFrom(acc1, acc0, web3.toWei(5), {from: acc0}) 0x5cee7cf60849283a0088d71483a606ba2101b500e13f972abada4f75781596bf
檢查后,acc0
不允許從acc1
發送:
truffle(rsk)> web3.fromWei(cfToken.allowance(acc1, acc0, {from: acc0}).toString(10)) // = '0'
我們授權acc0
從acc1
的交易中以acc1
的名義花費10個代幣:
truffle(rsk)> cfToken.approve(acc0, web3.toWei(10), {from: acc1}) 0x6e1a202f4ca7f43dfb28034952d54a572993b986a55857790aa51854afbc1fb4
在輸出日志中,我們看到函數已成功完成,并且日志顯示允許acc0
用于支出的金額。檢查allowance:
truffle(rsk)> web3.fromWei(cfToken.allowance(acc1, acc0, {from: acc0}).toString(10)) // = '10'
現在,如果我們再次執行支出交易:
truffle(rsk)> cfToken.transferFrom(acc1, acc0, web3.toWei(5), {from: acc0}) 0x41f750eabb6e0d3ab576aac0333b0d337ca61808aae1eeafa9d8e2a0b81b979b
我們得到狀態為“0x01”的成功交易。
再檢查一下余額:
truffle(rsk)> web3.fromWei(cfToken.balanceOf(acc0).toString(10)) // = '738.6' truffle(rsk)> web3.fromWei(cfToken.balanceOf(acc1).toString(10)) // = '261.4'
最后,如果我們簽署一個調用不可用函數的事務,我們將調用我們的回退函數。 簽署一個像這樣的交易:
truffle(rsk)> web3.eth.sendTransaction({from: acc0, to: cfToken.address}) 0x4106a287fc60669bf9682a73ec4c457b094c086ec7408a5dea95d200688c4ee9
將返回一個日志,其數據表示字符串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開發”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。