Dapp
我們可以讓網頁使用web3.js連線到我們本地端的IPC 或 RPC 來讀取資料顯示到網頁,而mainnet和testnet都一樣,因為都是從geth 讀取同步區塊鏈後用本機的IPC或RPC把資料以類似API
方式傳給網頁
實作
我們一樣先執行剛才的節點
geth --ipcdisable --rpc --rpcport 8104 --datadir "./privatechain/01" --networkid 123 --rpccorsdomain="*" --rpcapi="db,eth,net,web3,personal" --nodiscover --port=30310 console
下面是我們這次要加入的token合約
contract token {
mapping (address => uint) public coinBalanceOf;
event CoinTransfer(address sender, address receiver, uint amount);
/* Initializes contract with initial supply tokens to the creator of the contract */
function token(uint supply) {
coinBalanceOf[msg.sender] = supply;
}
/* Very simple trade function */
function sendCoin(address receiver, uint amount) returns(bool sufficient) {
if (coinBalanceOf[msg.sender] < amount) return false;
coinBalanceOf[msg.sender] -= amount;
coinBalanceOf[receiver] += amount;
CoinTransfer(msg.sender, receiver, amount);
return true;
}
}
var tokenSource = ' contract token { mapping (address => uint) public coinBalanceOf; event CoinTransfer(address sender, address receiver, uint amount); /* Initializes contract with initial supply tokens to the creator of the contract */ function token(uint supply) { coinBalanceOf[msg.sender] = supply; } /* Very simple trade function */ function sendCoin(address receiver, uint amount) returns(bool sufficient) { if (coinBalanceOf[msg.sender] < amount) return false; coinBalanceOf[msg.sender] -= amount; coinBalanceOf[receiver] += amount; CoinTransfer(msg.sender, receiver, amount); return true; } }'
把上面的部分複製到我們的geth console 中
然後進行編譯
var tokenCompiled= web3.eth.compile.solidity(tokenSource)
如出現 Error: The method eth_compileSolidity does not exist/is not available
代表solidity版本 > 1.6 需要用線上編譯 https://remix.ethereum.org/
然後把網頁上Deploy部分貼上 之後直接跳到本章節的步驟三
之後試著輸入以下,即可看到剛才compile後的部分
tokenCompiled["<stdin>:token"].info.abiDefinition //查看我們合約的API
[{
constant: false,
inputs: [{
name: "receiver",
type: "address"
}, {
name: "amount",
type: "uint256"
}],
name: "sendCoin",
outputs: [{
name: "sufficient",
type: "bool"
}],
payable: false,
type: "function"
}, {
constant: true,
inputs: [{
name: "",
type: "address"
}],
name: "coinBalanceOf",
outputs: [{
name: "",
type: "uint256"
}],
payable: false,
type: "function"
}, {
inputs: [{
name: "supply",
type: "uint256"
}],
payable: false,
type: "constructor"
}, {
anonymous: false,
inputs: [{
indexed: false,
name: "sender",
type: "address"
}, {
indexed: false,
name: "receiver",
type: "address"
}, {
indexed: false,
name: "amount",
type: "uint256"
}],
name: "CoinTransfer",
type: "event"
}]
設定帳戶
然後我們先用以下指令,確定我們鏈上有帳號(也可查看keystore資料夾)
如果沒有可打開Mist新增或輸入personal.newAccount()
Mac
/Applications/Ethereum\ Wallet.app/Contents/MacOS/Ethereum\ Wallet --rpc http://localhost:8104
Windows
先將以下加入環境變數
C:\Program Files\Mist
然後開啟terminal輸入
mist --rpc http://localhost:8104
之後輸入以下綁定帳號到節點
web3.miner.setEtherbase("輸入地址")
然後輸入以下來解鎖帳號(讓帳號可以交易)
personal.unlockAccount(web3.eth.accounts[0], "輸入此帳號的password")
接著把我們剛才的合約實例化,並部署
如果是solidity版本大於1.6用剛才的線上編譯器 然後點選deploy之後複製
然後先在terminal輸入 supply = 10000; 然後貼上剛才複製的部分
var supply = 10000;
var tokenContract = web3.eth.contract(tokenCompiled["<stdin>:token"].info.abiDefinition);
var token = tokenContract.new(
supply,
{
from:web3.eth.accounts[0],
data:tokenCompiled["<stdin>:token"].code,
gas: 1000000
}, function(e, contract){
if(e){console.log(e); }
if(!e) {
if(!contract.address) {
console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...");
} else {
console.log("Contract mined! Address: " + contract.address);
console.log(contract);
}
}
})
正常的話會出現如下
I0215 20:34:36.263099 internal/ethapi/api.go:1074] Tx(0x09d25084b1d471a48c371bb98f54dde88b59af24348a7b2b29a09bc91c7c9727) created: 0x14067c5707025c4dabba49949c0c166070b4f5c9
Contract transaction send: TransactionHash: 0x09d25084b1d471a48c371bb98f54dde88b59af24348a7b2b29a09bc91c7c9727 waiting to be mined...
再來為了要把合約加入Blockchain我們要用挖礦方式產生新區塊
因為在私鏈所以我們要自己挖
產生完Dag後接著挖到contract後可以stop
然後就可以輸入以下
browser_ballot_sol_token.coinBalanceOf(web3.eth.accounts[0])
即會出現餘額
監聽
在console貼上如下,因為我們剛contract有寫event
var event = browser_ballot_sol_token.CoinTransfer({}, '', function(error, result){
if (!error)
console.log("Coin transfer: " + result.args.amount + " tokens were sent. Balances now are as following: \n Sender:\t" + result.args.sender + " \t" + token.coinBalanceOf.call(result.args.sender) + " tokens \n Receiver:\t" + result.args.receiver + " \t" + token.coinBalanceOf.call(result.args.receiver) + " tokens" )
});
之後有人使用這個合約都會有通知
再來我們要試著轉一些token從帳號0給帳號1
(如果沒有一樣用錢包新增)
先解鎖兩個帳號
personal.unlockAccount(web3.eth.accounts[1], "輸入password")
personal.unlockAccount(web3.eth.accounts[0], "輸入password")
查看餘額
browser_ballot_sol_token.coinBalanceOf(web3.eth.accounts[1])
轉帳
browser_ballot_sol_token.sendCoin.sendTransaction(web3.eth.accounts[1], 1000, {from: web3.eth.accounts[0]})
成功會console如下
I0215 20:47:15.628190 internal/ethapi/api.go:1076] Tx(0x0bf7ec2dc727fb9d9943aeabca86c92616f178691f96667db251c16370b0d367) to: 0x14067c5707025c4dabba49949c0c166070b4f5c9
再來一樣要先挖礦
browser_ballot_sol_token.coinBalanceOf(web3.eth.accounts[1])
即可看到1000,即為剛才轉過去的
2.把剛才的合約部署到其他節點
為了使得其他人可以運行你的智能合約,你需要兩個資訊:
1.智能合約地址Address
2.智能合約ABI(Application Binary Interface),ABI其實就是一個有序的用戶手冊,描述了所有方法的名字和如何調用它們。
我們可以使用如下獲得其ABI和智能合約地址:
如solidity版本 > 1.6 一樣使用Remix進行合約ABI查看
點選Details 然後選 interface
查看地址 : 輸入browser_ballot_sol_token.address
browser_ballot_sol_token . address
執行另一個節點
geth --ipcdisable --rpc --rpcport 8105 --datadir "./privatechain/02" --networkid 123 --rpccorsdomain="*" --rpcapi="db,eth,net,web3,personal" --nodiscover --port=30311 console
接著我們到另一個節點的console輸入如下,把ABI與Address更改為剛讀取出來的值(建議開一個檔案修改,之後再貼到console,因為code多console不好修改)
var token = web3.eth.contract(ABI).at(Address);
接著每個節點有自己的帳戶,所以我們先取的節點一的地址
web3.eth.accounts[1]
然後到另一個terminal把地址貼上到框框中
token.coinBalanceOf("0x7d92564bf8e41e093f265da1532ef4143f398461")
如發現金額仍然是0,但應該要是1000,我們可以跟另一個節點做區塊鏈同步即可解決
所以先把第一個節點加入,步驟如下
於第一個節點輸入admin.nodeInfo
=> 複製enode url=> 第二個節點輸入admin.addPeer("剛才複製的enode url")
之後再到第二個節點輸入以下,即可同步區塊
miner.start(1)
記得先解鎖
web3.miner.setEtherbase(web3.eth.accounts[0]);
personal.unlockAccount(web3.eth.accounts[0], "輸入此帳號的password");
此時第二個節點也會出現相同金額了!
之後有新節點加入都是類似輸入如下,並且addPeer
var token = web3.eth.contract([{
constant: false,
inputs: [{
name: "receiver",
type: "address"
}, {
name: "amount",
type: "uint256"
}],
name: "sendCoin",
outputs: [{
name: "sufficient",
type: "bool"
}],
payable: false,
type: "function"
}, {
constant: true,
inputs: [{
name: "",
type: "address"
}],
name: "coinBalanceOf",
outputs: [{
name: "",
type: "uint256"
}],
payable: false,
type: "function"
}, {
inputs: [{
name: "supply",
type: "uint256"
}],
payable: false,
type: "constructor"
}, {
anonymous: false,
inputs: [{
indexed: false,
name: "sender",
type: "address"
}, {
indexed: false,
name: "receiver",
type: "address"
}, {
indexed: false,
name: "amount",
type: "uint256"
}],
name: "CoinTransfer",
type: "event"
}]).at("0x14067c5707025c4dabba49949c0c166070b4f5c9");
接著我們看下一章來做成一個網頁
Last updated