本文是參考《【區(qū)塊鏈】DOCKER部署量子鏈私有網(wǎng)絡(luò)環(huán)境以及部署智能合約實踐》和比特幣的命令行操作谜喊,來通過量子鏈源碼來搭建私有測試網(wǎng)絡(luò)啃擦,并發(fā)布智能合約讶隐。主要是不習(xí)慣docker的操作(命令行太長了)抖拦,因此就用源代碼重來了一次。
1.?源代碼編譯
參考https://github.com/qtumproject/qtum在ubuntu16上編譯源代碼诫睬,成功后在src目錄下生成了qtumd煞茫,qtum-cli文件。
2.?啟動regtest網(wǎng)絡(luò)
在src目錄下執(zhí)行:
./qtumd -server -regtest?就可以啟動regtest網(wǎng)絡(luò)
3.?查詢當(dāng)前帳號信息
再啟動一個terminal摄凡,在src目錄下執(zhí)行:
./qtum-cli -regtest listaccounts
輸出:
{
? "": 0.00000000,
}
4.?查詢帳號對應(yīng)的地址
./qtum-cli -regtest getaccountaddress ""
輸出:
qXgQefNvuvRVsk2DPuqopqRxEujruTa32T
5.?充值
由于是regtest網(wǎng)絡(luò)续徽,自己挖礦就有了
需要生成5000個區(qū)塊(比特幣挖100個就有錢了):
./qtum-cli -regtest generate 5000
然后查看賬戶:
./qtum-cli -regtest getbalance
90000000.00000000
看起來不少
6.?新增一個帳號
./qtum-cli -regtest getnewaddress "elikong"
qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42
下面我們就可以實現(xiàn)目標(biāo):
帳號""地址qXgQefNvuvRVsk2DPuqopqRxEujruTa32T
向帳號"elikong"地址qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42
轉(zhuǎn)賬100btc
7.?轉(zhuǎn)賬
./qtum-cli -regtest sendtoaddress qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42100
8.?挖礦確認(rèn)
./qtum-cli?-regtest?generate?1
然后查詢數(shù)量
./qtum-cli?-regtest?listaccounts
{
? "": 90019899.99923200,
? "elikong": 100.00000000
}
可以看到elikong帳號有了100btc
9.?查看系統(tǒng)內(nèi)置的智能合約
./qtum-cli -regtest listcontracts
輸出:
{
? "0000000000000000000000000000000000000083": 0.00000000,
? "0000000000000000000000000000000000000082": 0.00000000,
? "0000000000000000000000000000000000000081": 0.00000000,
? "0000000000000000000000000000000000000084": 0.00000000,
? "0000000000000000000000000000000000000080": 0.00000000
}
10.?編寫智能合約
打開http://remix.ethereum.org,輸入:
pragma solidity ^0.4.0;
contract Greeter????????
{
??? address creator;????
??? string greeting = "hello";????
??? function Greeter() public??
??? {
??????? creator = msg.sender;
???? //?? greeting = _greeting;
??? }
??? function greet() constant returns (string)?????????
??? {
??????? return greeting;
??? }
??? function setGreeting(string _newgreeting)
??? {
??????? greeting = _newgreeting;
??? }
???? /**********
???? Standard kill() function to recover funds
???? **********/
??? function kill()
??? {
??????? if (msg.sender == creator)
??????????? suicide(creator);? // kills this contract and sends remaining funds back to creator
??? }
}
點擊右邊的detail亲澡,bytecode里面復(fù)制object的內(nèi)容:
60806040526040805190810160405280600581526020017f68656c6c6f0000000000000000000000000000000000000000000000000000008152506001908051906020019061004f9291906100a2565b5034801561005c57600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610147565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100e357805160ff1916838001178555610111565b82800160010185558215610111579182015b828111156101105782518255916020019190600101906100f5565b5b50905061011e9190610122565b5090565b61014491905b80821115610140576000816000905550600101610128565b5090565b90565b61038a806101566000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b51461005c578063a413686214610073578063cfae3217146100dc575b600080fd5b34801561006857600080fd5b5061007161016c565b005b34801561007f57600080fd5b506100da600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101fd565b005b3480156100e857600080fd5b506100f1610217565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610131578082015181840152602081019050610116565b50505050905090810190601f16801561015e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156101fb576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b565b80600190805190602001906102139291906102b9565b5050565b606060018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102af5780601f10610284576101008083540402835291602001916102af565b820191906000526020600020905b81548152906001019060200180831161029257829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102fa57805160ff1916838001178555610328565b82800160010185558215610328579182015b8281111561032757825182559160200191906001019061030c565b5b5090506103359190610339565b5090565b61035b91905b8082111561035757600081600090555060010161033f565b5090565b905600a165627a7a72305820eb4609861a4d53088ea938f7cc4a477805113f4f31baa67746f137848c4450f90029
11.?發(fā)布智能合約
輸出:
{
? "txid": "1cbe4562ede3ddba2e507d3fad73fc47a8d6d098fd47a32cf2feb4032a1cf901",
? "sender": "qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42",
? "hash160": "7f4afe6ab9ab538f7d28f08c2687f7681d1cd0d7",
? "address": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b"
}
檢查智能合約:
./qtum-cli -regtest generate 1
./qtum-cli -regtest listcontracts
輸出:
{
? "0000000000000000000000000000000000000082": 0.00000000,
? "0000000000000000000000000000000000000080": 0.00000000,
? "0000000000000000000000000000000000000083": 0.00000000,
? "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b": 0.00000000,
? "0000000000000000000000000000000000000084": 0.00000000,
? "0000000000000000000000000000000000000081": 0.00000000
}
上面紅色部分就是剛才發(fā)布的合約地址
查詢詳細(xì):
./qtum-cli -regtest getaccountinfo e62b8bc805c33184d9713f7fb1e20606dcfe7a9b
輸出:
{
? "address": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",
? "balance": 0,
? "storage": {
??? "290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563": {
????? "0000000000000000000000000000000000000000000000000000000000000000": "0000000000000000000000007f4afe6ab9ab538f7d28f08c2687f7681d1cd0d7"
??? },
??? "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6": {
????? "0000000000000000000000000000000000000000000000000000000000000001": "68656c6c6f00000000000000000000000000000000000000000000000000000a"
??? }
? },
? "code": "608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b51461005c578063a413686214610073578063cfae3217146100dc575b600080fd5b34801561006857600080fd5b5061007161016c565b005b34801561007f57600080fd5b506100da600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101fd565b005b3480156100e857600080fd5b506100f1610217565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610131578082015181840152602081019050610116565b50505050905090810190601f16801561015e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156101fb576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b565b80600190805190602001906102139291906102b9565b5050565b606060018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102af5780601f10610284576101008083540402835291602001916102af565b820191906000526020600020905b81548152906001019060200180831161029257829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102fa57805160ff1916838001178555610328565b82800160010185558215610328579182015b8281111561032757825182559160200191906001019061030c565b5b5090506103359190610339565b5090565b61035b91905b8082111561035757600081600090555060010161033f565b5090565b905600a165627a7a72305820eb4609861a4d53088ea938f7cc4a477805113f4f31baa67746f137848c4450f90029"
}
12.?運行智能合約
繼續(xù)回到http://remix.ethereum.org里面的detail炸宵,復(fù)制FUNCTIONHASHES里面的數(shù)據(jù):
{
??? "cfae3217": "greet()",
??? "41c0e1b5": "kill()",
??? "a4136862": "setGreeting(string)"
}
./qtum-cli -regtest callcontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9bcfae3217
輸出:
{
? "address": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",
? "executionResult": {
??? "gasUsed": 22742,
??? "excepted": "None",
??? "newAddress": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",
??? "output": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000",
??? "codeDeposit": 0,
??? "gasRefunded": 0,
??? "depositSize": 0,
??? "gasForDeposit": 0
? },
? "transactionReceipt": {
??? "stateRoot": "c0a81c3cac5aa655116ca988620a4f88483244e2e985d4665dc8c04c959dcb2d",
??? "gasUsed": 22742,
??? "bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
??? "log": [
??? ]
? }
}
由于ethabi在ubuntu上只能通過cargo安裝,因此需要先安裝cargo
sudo apt install cargo
然后安裝ethabi
cargo install ethabi-cli
查看合約輸出內(nèi)容谷扣,就是解碼上面的output內(nèi)容
ethabi decode params -t string 0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000
輸出:
string hello
這里需要使用ethabi構(gòu)造輸入?yún)?shù)
先從http://remix.ethereum.org里面的detail復(fù)制abi,保存為文件greet.json
[
????? {
?????????? "constant": false,
?????????? "inputs": [],
?????????? "name": "kill",
?????????? "outputs": [],
?????????? "payable": false,
?????????? "stateMutability": "nonpayable",
?????????? "type": "function"
????? },
????? {
?????????? "constant": false,
?????????? "inputs": [
???????????????? {
????????????????????? "name": "_newgreeting",
????????????????????? "type": "string"
???????????????? }
?????????? ],
?????????? "name": "setGreeting",
?????????? "outputs": [],
?????????? "payable": false,
?????????? "stateMutability": "nonpayable",
?????????? "type": "function"
????? },
????? {
?????????? "constant": true,
?????????? "inputs": [],
?????????? "name": "greet",
?????????? "outputs": [
???????????????? {
????????????????????? "name": "",
????????????????????? "type": "string"
???????????????? }
?????????? ],
?????????? "payable": false,
?????????? "stateMutability": "view",
?????????? "type": "function"
????? },
????? {
?????????? "inputs": [],
?????????? "payable": false,
?????????? "stateMutability": "nonpayable",
?????????? "type": "constructor"
????? }
]
然后構(gòu)造參數(shù):
ethabi encode function greet.json setGreeting -p "hello world" --lenient
輸出:
a41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b68656c6c6f20776f726c64000000000000000000000000000000000000000000
這里對比兩個命令
l?callcontract?鏈下完成捎琐,不會在區(qū)塊鏈上產(chǎn)生記錄会涎。不消耗gas
l?sendtocontract?鏈上完成,需要同步瑞凑,會消耗gas
我們使用下面的命令
sendtocontract?"contractaddress""data"?(amount gaslimit gasprice senderaddress broadcast)
Send funds and data to a contract.
輸出:
{
? "txid": "af73f3f087a351ee672bdcd0d93a61b79a72ebc694bbff489b17089e68401c5c",
? "sender": "qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42",
? "hash160": "7f4afe6ab9ab538f7d28f08c2687f7681d1cd0d7"
}
查詢結(jié)果:
./qtum-cli -regtest callcontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9bcfae3217
輸出:
{
? "address": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",
? "executionResult": {
??? "gasUsed": 22742,
??? "excepted": "None",
??? "newAddress": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",
??? "output": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b68656c6c6f20776f726c64000000000000000000000000000000000000000000",
??? "codeDeposit": 0,
??? "gasRefunded": 0,
??? "depositSize": 0,
??? "gasForDeposit": 0
? },
? "transactionReceipt": {
??? "stateRoot": "6fa927d9a6d5b8794215a5ad465fbd498c051ca3d28046a508fd46aa5f2124ef",
??? "gasUsed": 22742,
??? "bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
??? "log": [
??? ]
? }
}
查詢output:
ethabi decode params -t string 0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b68656c6c6f20776f726c64000000000000000000000000000000000000000000
輸出:
string hello world
說明修改成功
(這里沒有挖礦末秃,是因為qtum后續(xù)自動挖礦了)
15.?合約銷毀
就是調(diào)用合約的函數(shù)kill()
./qtum-cli -regtest sendtocontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9b41c0e1b5
輸出:
{
? "txid": "15bd8155a735804946ac5cd24e21a7c414a1806bb9bf6cb65d3431b78628ce84",
? "sender": "qYn9XGorExumdxEdx1TVDXBXLzKYFFMRXN",
? "hash160": "a6f3e9d2c239bab50b60fb5365d1a3e01f861507"
}
查詢合約:
./qtum-cli -regtest listcontracts
輸出:
{
? "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b": 0.00000000,
? "0000000000000000000000000000000000000083": 0.00000000,
? "0000000000000000000000000000000000000084": 0.00000000,
? "0000000000000000000000000000000000000080": 0.00000000,
? "0000000000000000000000000000000000000082": 0.00000000,
? "0000000000000000000000000000000000000081": 0.00000000
}
實際并沒用刪除,因為kill函數(shù)內(nèi)部判斷了只能創(chuàng)建者刪除籽御,因此练慕,我們使用創(chuàng)建者刪除:
輸出:
error code: -3
error message:
Sender address does not have any unspent outputs
提示沒有utxo,但是查詢賬戶
./qtum-cli -regtest listaccounts
{
? "": 91959699.69510800,
? "elikong": 198.76914800
}
有資金技掏,為啥沒有utxo呢铃将?
./qtum-cli -regtest getaccountaddress "elikong"???
輸出:
qY26EDJjSA2S9wjXdLm9JNtosV52eJN6Cg
發(fā)現(xiàn)elikong的地址發(fā)生了變化,以前是qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42
這個應(yīng)該就是和比特幣不同的地方了哑梳,量子鏈的技術(shù)文章里面說實現(xiàn)了虛擬賬戶層劲阎,估計這塊就是一個賬戶對應(yīng)了多個地址,先不管這個鸠真,繼續(xù)給qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42轉(zhuǎn)賬
./qtum-cli -regtest sendtoaddress qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42 100
然后繼續(xù)執(zhí)行消耗合約:
./qtum-cli -regtest sendtocontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9b41c0e1b5 0 250000 0.00000049qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42
輸出:
{
? "txid": "04ca077bd721063aa0062b7a5d8c3a058181872741e2a88b389fe82dda59ebd1",
? "sender": "qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42",
? "hash160": "7f4afe6ab9ab538f7d28f08c2687f7681d1cd0d7"
}
查詢合約:
./qtum-cli -regtest listcontracts
輸出:
{
? "0000000000000000000000000000000000000082": 0.00000000,
? "0000000000000000000000000000000000000083": 0.00000000,
? "0000000000000000000000000000000000000084": 0.00000000,
? "0000000000000000000000000000000000000080": 0.00000000,
? "0000000000000000000000000000000000000081": 0.00000000
}
合約確實被刪除了
(或者用./qtum-cli -regtest getaccountinfo e62b8bc805c33184d9713f7fb1e20606dcfe7a9b)