發表文章

目前顯示的是有「智能合約」標籤的文章

Upgradable smart contract using zos

smart contract跟一般程式最大的差異,就是smart contract上了鏈就不能改了(這是區塊鏈的特性也是優點,但是如果真的有bug,麻煩就大了...)。所以今天要介紹的是,如何用 ZeppelinOS 來實作upgradeable smart contract,可升級的smart contract。 版本  - zos: 2.1.0  - Truffle: 5.0.1 OpenZeppelin 對smart contract的開發者一定不陌生,提供相當多smart contract的範例程式。Zeppelin部落格有介紹如何使用proxy contract實作可升級的contract,這是他們 proxy patterns的設計 ,之後有機會再深入介紹proxy pattern。本篇主要在介紹如何使用 zos 部署可升級的contract。(本篇需要有使用過truffle的經驗) Deploy contracts 環境部分,先安裝Node.js跟npm,跟Ganache(或Ganache-cli)。 Deploy your first project 有詳細地介紹如何使用zos部署。 先安裝ZeppelinOS npm install --global zos 再來建立專案 mkdir MyProject cd MyProject 初始化專案 npm init zos init MyProject npm install zos-lib 這個時候,資料夾內容就跟下過 truffle init 一樣,有 contracts , migrations 資料夾, truffle-config.js 等。以上環境就都建置完成了,再來就是寫contract了,這裡直接用官方的範例 pragma solidity ^ 0.4 .24; import "zos-lib/contracts/Initializable.sol" ; contract MyContract is Initializable { uint256 public x; string public s; function initialize(uint256...

Ethereum Token - ERC20 mint 跟 burn

這篇會著重在erc20 smart contract實作mint跟burn的部分,所以需要先了解erc20喔! erc20 token在設計上可以a.預先產生,b.產生部分然後部分用挖的(mint)或是c.都用挖的。當然在應用上跟token屬性有關,例如是屬於security token或是utility token。簡單來說,像是股票可以獲利或是配息概念的算是security token,需要受各國法令監管,那utility token就比較像是點數的概念,至於細節怎麼分不是本篇重點。 mint的使用時機,例如在crowd sale時,每一筆進入crowd sale的錢,crowd sale 的contract 就會呼叫token contract去產生某個數量的token,這個動作就可以稱作mint。也有不用挖的,一開始就產生好,例如秘銀(MITH),從etherscan可以看到token contract怎麼寫的,這裡可以看到 MITH的contract 。當然你想產多少就多少,不過就看有沒有人買單 XD 回到正題,要"挖"聽起來,就覺得很複雜,但其實smart contract的本質就是記帳,所以其實就只是數字上的加減而已,下面是範例程式 function mint(address _to, uint256 _amount) public { totalSupply_ = totalSupply_.add(_amount); balances[_to] = balances[_to].add(_amount); emit Mint(_to, _amount); } 其實就只是把 增加個人的token的數量 ,然後增 加整個contract token的總數 而已。當然,這種function需要做權限的控管,不然大家都可以自己產,token就會沒價值了。講完"挖"應該很好想像怎麼burn吧?! 就是把數量減掉就好了!(當然這也需要做權限控管) function _burn(address _who, uint256 _value) public { balances[_who] = balances[_who].sub(_value); totalSu...

使用Truffle作smart contract測試及debug - III debug

版本 - truffle 4.1.11 一不小心,就寫到了III...沒有偷文章數的意思阿~~~ 不過我在這邊先破題,truffle的debug功能,還在發展中,其實沒有想像中的方便跟powerful,例如在debug的過程還滿常會發生exception的(這還滿常發生的)、 無法得知 global變數內容...等等。官方一樣有很詳細的解說,可以看 這裡 。 要debug其實很簡單,先複製你要debug的transaction hash,然後 $ truffle debug 0x1d8791c26e7aa941c295bed8ed81a3d5fb4790ed9f84a76e2d4341c6c4b09131 接著會看到指令 Commands: (enter) last command entered (step next) (o) step over, (i) step into, (u) step out, (n) step next (;) step instruction, (p) print instruction, (h) print this help, (q) quit (b) toggle breakpoint, (c) continue until breakpoint (+) add watch expression (`+:<expr>`), (-) remove watch expression (-:<expr>) (?) list existing watch expressions (v) print variables and values, (:) evaluate expression - see `v` o/i/u/n:一般有在用IDE debug的都知道,就不做解釋 +:可以加觀察的變數 v:就是顯示目前變數的值(global目前都是空值) 一步一步debug就會看到在哪行source code,像是這樣 Token777.sol: 277 : if (_to== address ( 0x00 )) return ; 278 : TokenReceiver x; 279 : if ( doesContractIm...

使用Truffle作smart contract測試及debug - II 測試

版本 - truffle 4.1.11 延續 上篇 ,繼續講測試的部分 寫test case有兩個方式,一個是用 solidity 另一個是用 javascript ,官方文件寫得還滿清楚的。記得你寫的test case的檔案,要放在 test/ 下 先介紹solidity的寫法,要先import下面這兩個smart contract,當然也要記得import你自己的smart contract import "truffle/Assert.sol" ; import "truffle/DeployedAddresses.sol" ; import "../contracts/Token777.sol" ;  再來是命名規則,contract要以  Test   為開頭,測試function要以  test  為開頭 contract TestTaroToken { function testMint () public { Token777 token = Token777 (DeployedAddresses. Token777 ()); address user = 0x2849f61e08B66A3b0eC2512613092174Df19Db1e ; uint base = token. balanceOf (user); uint incremental = 30000000000000000000 ; token. mint (user,incremental, "" ); Assert. equal (token. balanceOf (user), base+incremental, "balance is not equal" ); } } test case看起來相當直覺,就是先取得contract object後,呼叫mint(你想測試的function)這個function,最後用Assert確認結果,跟我們一般寫UT很相似。當然也有提供 beforeAll , beforeEach , afterAll 跟  afterEach...

使用Web3j 快速實作 Oracle - II 使用smart contract wrapper

Part II 拖得有點久... 其實產生出wrapper後,直接看source code,就大概懂怎麼使用了,web3j 直接把smart contract的function轉成Java function。接下來會解釋的就是怎麼load contract跟怎麼subscribe events。 備註:這裡的範例是用 web3j 3.1.1 所產生 How to load smart contract wrapper 首先,看到load的方法有兩個,其實只有差在Credentials跟TransactionManager public static Ballot load (String contractAddress , Web3j web3j , Credentials credentials , BigInteger gasPrice , BigInteger gasLimit) { return new Ballot(contractAddress , web3j , credentials , gasPrice , gasLimit) ; } public static Ballot load (String contractAddress , Web3j web3j , TransactionManager transactionManager , BigInteger gasPrice , BigInteger gasLimit) { return new Ballot(contractAddress , web3j , transactionManager , gasPrice , gasLimit) ;}   Credentials :     這是Web3j的基本元件,大概沒什麼好說的(被揍飛 XD),還是附一下範例,基本就是帶入一串私鑰即可 Credentials cred = Credentials. create ( privatekey ); 如果,你的應用沒有需要快速連續送交易,或是不要求在listen event的間隔,其實這樣就可以了。但若有其中一項需求,這個方式就無法滿足,需要用TransactionManager。 TransactionMa...

使用Web3j 快速實作 Oracle -I建立smart contract wrapper

本篇是在介紹,如何使用Web3j能快速開發Oracle,不用一個一個刻跟ABI互動的function 因為整個ethereum都還在發展中,相關的工具也是,所以變動很快,這邊我使用的是 Web3j 2.3.1 ,搭配 Solidity 0.4.17 不清楚Oracle的,可以參考 這篇 ,寫得相當詳細跟清楚 簡單來說,EVM是一個封閉環境,不可跟外界接觸,不過event(可以想作是一般寫程式的log)是會被寫到鏈上的,寫到鏈上就代表是公開網路,大家都可以去讀取,再透過程式(也就是Oracle)去監聽特地的event。然後smart contract裡的function本來就是可以從外部被執行的。所以就是透過監聽event跟執行smart contract的function,進而從外界可以跟smart contract 做互動。 首先,先撰寫你自己的smart contract,下面這是我從官方copy過來的範例,然後加了兩個event,完整的smart contract可以看 這裡 pragma solidity ^ 0 . 4 . 17 ; contract Ballot { event EventVote ( uint id, address voter, uint time); event EventNewVoter ( address voter); function giveRightToVote ( address voter) { require (( msg . sender == chairperson) && ! voters[voter].voted && (voters[voter].weight == 0 )); voters[voter].weight = 1 ; EventNewVoter (voter); } function vote ( uint proposal) { Voter storage sender = voters[ msg . sender ]; require ( ! sender.voted); ...