以太坊私鏈搭建、truffle項目開發

本文實現如下目標:git

  1. 搭建一條以太坊私鏈
  2. 用企業級開發方式開發、部署一個項目
  3. 分析truffle執行過程
  4. solidity、web3等的一些說明

Token ERC20標準

contract ERC20Interface {
    function totalSupply() public constant returns (uint);
    function balanceOf(address tokenOwner) public constant returns (uint balance);
    function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
    function transfer(address to, uint tokens) public returns (bool success);
    function approve(address spender, uint tokens) public returns (bool success);
    function transferFrom(address from, address to, uint tokens) public returns (bool success);

    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}

整個區塊鏈的全部數據都存儲在一個levelDB的數據庫中,其物理文件存儲在:~/Library/Ethereum/geth/chaindata/ 下。github

搭建以太坊私鏈

一、建立目錄ethweb

mkdir eth

二、編寫創世區塊,放入eth目錄下。chrome

{
  "config": {
    "chainId": 10,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "alloc"      : {},
  "coinbase"   : "0x0000000000000000000000000000000000000000",
  "difficulty" : "0x20000",
  "extraData"  : "",
  "gasLimit"   : "0xffffffff",
  "nonce"      : "0x0000000000000042",
  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp"  : "0x00"
}

其中,alloc用來預設帳號和帳號的以太幣數量,此處不預設,須要的時候再建立。數據庫

  • [ ] 注意
gasLimit要修改大點,否則部署智能合約的時候,合約須要消耗的gas超過這個limit會發生失敗。

chainId是EIP155裏定義的發送交易到哪一種鏈的方式,(EIP是以太坊改進建議)。這裏設置爲10,truffle.js裏的network_id也得是10,否則交易的時候會報invalid sender的錯誤。npm

CHAIN_ID Chain(s)
1 Ethereum mainnet
2 Morden (disused), Expanse mainnet
3 Ropsten
4 Rinkeby
30 Rootstock mainnet
31 Rootstock testnet
42 Kovan
61 Ethereum Classic mainnet
62 Ethereum Classic testnet
1337 Geth private chains (default)

三、建立創世塊json

geth --datadir "./" init genesis.json

--datadir是指定區塊鏈數據和帳戶的存儲目錄。\
這句話的做用是:\
建立2個數據庫chaindata和lightchaindata,並把genesis.json的數據分別寫入這兩個leveldb中。segmentfault

四、啓動以太坊,日誌寫入文件,同時進入js交互控制檯。api

geth --datadir "./" --rpc --rpccorsdomain="*"  console 2>>00.glog

rpccorsdomain是容許chrome插件MetaMask,remix等跨域訪問web3接口。跨域

如今這條私鏈上沒有帳戶沒有交易。

五、在啓動礦工進行挖礦以前咱們必須建立至少一個帳戶,並將其設爲ether base帳戶,這樣礦工挖礦所得的以太幣將自動存入咱們設置的帳戶。
由於部署合約須要消耗以太幣,這裏在私鏈上經過挖礦得到以太幣。

建立帳戶(帳戶是一對密鑰)

personal.newAccount(「your account passwd」)

輸出了一個帳戶地址:

0xad30387c05b527a85f45186c2b8aab5e1af2f227

這個帳戶的私鑰文件就存儲在$datadir/keystore文件夾下。

六、將這個帳戶設置爲礦工etherbase

miner.setEtherbase(eth.accounts[0])

設置以後,一旦啓動挖礦,則挖礦收益就打入這個帳戶,因此設置以後這個帳戶也叫coinbase。

以上私鏈搭建完成。

MetaMask導入帳戶

MetaMask以太錢包,導入在geth控制檯建立的那個帳號,而後用這個帳戶去領養寵物。

首先登陸MetaMask,而後點擊右上角用戶那裏->點擊導入帳戶->選擇json file類型->選擇瀏覽到keystore下對應帳戶文件->輸入這個帳戶的密碼。

完成上述步驟,就導入了geth新建的帳戶。

關於MetaMask和帳戶的關係理解:

MetaMask就是以太錢包。

  • [x] 這個錢包的私鑰文件就僅僅存儲在你本身的設備上,丟失了就沒了。
  • [x] 你的密碼就是這個錢包的私鑰的加密簽名。
  • [x] 錢包地址就是公鑰。

帳戶就是一對公私鑰(各爲256位的數字),用地址(去掉公鑰前12字節,剩餘160位,用16進制編碼是40個字符)表示。

在MetaMask上建的帳戶和geth裏建的帳戶,都是典型的外部擁有帳戶(參見以太坊基礎概念專題);

你也能夠根據帳戶的提示詞、私鑰文件導入其餘帳戶到同一錢包(注意導入的帳戶要和選擇的鏈網絡<公鏈、私鏈、測試鏈等>匹配,也就是該鏈裏先有此帳戶才能導入,不然只能先建立,能夠在錢包界面上建立也能夠在geth裏用命令建立)。

項目開發

這裏用truffle+私鏈的方式演示企業級項目開發。

項目源碼公佈在:
https://github.com/m3shine/et...

建立項目

項目所需工具、概念和項目結構描述參見個人另外一篇專欄文章:
https://segmentfault.com/a/11...

此項目包含如下功能

  • [x] 領養寵物(僅展現)
  • [x] 發行幣(token)

領養寵物

發行幣(token)

發行總量爲20億的傻幣,代號SB。

首先須要一個合約,其次明確建立合約須要消耗的是gas(以以太幣支付),而不是消耗SB。

基於以太坊的幣(token)要和以太幣區分開。

經過truffle向以太坊私鏈部署合約

一、在用truffle向私鏈部署合約前,須要解鎖帳戶。而一個帳戶被建立時以太坊默認是將其鎖住的。

解鎖帳戶

personal.unlockAccount(eth.accounts[0], "you account passwd", 15000)

第三個參數是解鎖時間——單位秒。

這裏的accounts[0]就是咱們搭建私鏈的時候建立的第一個帳戶。

二、確保以太坊私鏈啓動中,並有礦工在挖礦(出塊)

查看是否有pending的交易,應該沒有,有的話會阻塞交易。

txpool.status
miner.start()

三、部署智能合約

在移植以前,

  • [ ] 首先須要有一個帳戶並設爲礦工地址(默認第一個帳戶就是礦工地址);
  • [ ] 其次須要解鎖帳戶;
  • [ ] 再次須要帳戶裏有錢(eth);
  • [ ] 最後須要有礦工在出塊(挖礦)才能完成移植。

cd到truffle工程目錄下,執行:

truffle migrate --reset --network development

--network development是根據truffle.js文件裏定義的網絡使用的:

networks: {
    development: {
      host: "127.0.0.1",
      port: 8545,
      network_id: "10" // 這裏的id必須與創世區塊genesis裏的chainId同樣。
    }
  }

--reset

使用reset能夠從新執行全部(默認只執行新增而未執行的)migration腳本,但在真實網絡裏這樣作不切實際,由於每次執行都須要消耗gas。\
在區塊鏈中,每一個部署都是一個交易,每一個交易都是不可逆的。這種架構背後的所有理念是容許咱們添加/升級合約並僅從新部署受影響的合同。\
想象一下咱們已經升級了一個合約如TokenSB.sol,要怎樣部署這個合約而不從新部署其餘合約?咱們就須要新建一個部署腳本,放在migrations目錄下,再執行

truffle migrate

這時將從這個最新的部署腳本開始執行。

看一下移植的輸出:

Compiling ./contracts/TokenSB.sol...
Writing artifacts to ./build/contracts

Using network 'development'.

Running migration: 1_initial_migration.js
  Replacing Migrations...
  ... 0x751b8cc80859a4c9fa39aa27b6ee2e89fcbe49713ed3f5fb8f788a886878b714
  Migrations: 0x7b8d3f0ce869c8ffbfaff027a7a21fab6f0e179c
Saving successful migration to network...
  ... 0x4b6ac5acc4b6965a6463db905eb33019d48ff64ccf3e1cf19d6020dbf0d8f2b6
Saving artifacts...
Running migration: 2_deploy_contract.js
  Replacing TokenSB...
  ... 0xda750feafdb742c16bb56c57beb84a21346cabc847af19faa98c3fddb47c4057
  TokenSB: 0xb90598a717180f21a13432d5cc7f1823267c9a95
Saving successful migration to network...
  ... 0x188d17d0ffdbd6ce41e2ca4a37b0e4ae01b909aa148417e48c960d38bd12cd6d
Saving artifacts...

這是發生了4筆交易,其中兩筆是「合約建立」交易,建立了2個合約(對應生成2個合約帳戶),另外兩筆交易是經過礦工帳戶支付gas給Migration合約帳戶來改變它的狀態,具體改變了什麼狀態?在Migraion.sol裏的setCompleted函數用來更新部署次數,每執行一個migrate腳本次數加1,改變的這個狀態就是最新的部署次數!

upgraded.setCompleted(last_completed_migration);

4筆交易:\
0x751b8cc80859a4c9fa39aa27b6ee2e89fcbe49713ed3f5fb8f788a886878b714\
0x4b6ac5acc4b6965a6463db905eb33019d48ff64ccf3e1cf19d6020dbf0d8f2b6\
0xda750feafdb742c16bb56c57beb84a21346cabc847af19faa98c3fddb47c4057\
0x188d17d0ffdbd6ce41e2ca4a37b0e4ae01b909aa148417e48c960d38bd12cd6d

2個合約帳戶:\
0x7b8d3f0ce869c8ffbfaff027a7a21fab6f0e179c\
0xb90598a717180f21a13432d5cc7f1823267c9a95

geth日誌裏對應打印出:

INFO [04-09|16:47:03] Submitted contract creation              fullhash=0x751b8cc80859a4c9fa39aa27b6ee2e89fcbe49713ed3f5fb8f788a886878b714 contract=0x7b8D3F0CE869c8fFBFAfF027a7a21fAB6F0e179c
INFO [04-09|16:47:03] Commit new mining work                   number=11 txs=1 uncles=0 elapsed=2.004s
INFO [04-09|16:47:04] Successfully sealed new block            number=11 hash=fd0e4e…3955ff
INFO [04-09|16:47:04] 🔗 block reached canonical chain          number=6  hash=76cc1a…87326d
INFO [04-09|16:47:04] 🔨 mined potential block                  number=11 hash=fd0e4e…3955ff
INFO [04-09|16:47:04] Commit new mining work                   number=12 txs=0 uncles=0 elapsed=107.73µs
INFO [04-09|16:47:04] Submitted transaction                    fullhash=0x4b6ac5acc4b6965a6463db905eb33019d48ff64ccf3e1cf19d6020dbf0d8f2b6 recipient=0x7b8D3F0CE869c8fFBFAfF027a7a21fAB6F0e179c
INFO [04-09|16:47:04] Successfully sealed new block            number=12 hash=e3408a…076693
INFO [04-09|16:47:04] 🔗 block reached canonical chain          number=7  hash=5ce86f…e788a4
INFO [04-09|16:47:04] 🔨 mined potential block                  number=12 hash=e3408a…076693
INFO [04-09|16:47:04] Commit new mining work                   number=13 txs=1 uncles=0 elapsed=323.85µs
INFO [04-09|16:47:05] Successfully sealed new block            number=13 hash=c7d419…3bb02a
INFO [04-09|16:47:05] 🔗 block reached canonical chain          number=8  hash=043c14…6b2ee9
INFO [04-09|16:47:05] 🔨 mined potential block                  number=13 hash=c7d419…3bb02a
INFO [04-09|16:47:05] Commit new mining work                   number=14 txs=0 uncles=0 elapsed=179.885µs
INFO [04-09|16:47:05] Successfully sealed new block            number=14 hash=940098…434280
INFO [04-09|16:47:05] Mining too far in the future             wait=2s
INFO [04-09|16:47:05] 🔗 block reached canonical chain          number=9  hash=09c495…d093d3
INFO [04-09|16:47:05] 🔨 mined potential block                  number=14 hash=940098…434280
INFO [04-09|16:47:05] Submitted contract creation              fullhash=0xda750feafdb742c16bb56c57beb84a21346cabc847af19faa98c3fddb47c4057 contract=0xb90598a717180F21a13432d5Cc7F1823267c9a95
INFO [04-09|16:47:07] Commit new mining work                   number=15 txs=1 uncles=0 elapsed=2.005s
INFO [04-09|16:47:08] Successfully sealed new block            number=15 hash=fea615…3d68a2
INFO [04-09|16:47:08] 🔗 block reached canonical chain          number=10 hash=f93cfa…2ed290
INFO [04-09|16:47:08] 🔨 mined potential block                  number=15 hash=fea615…3d68a2
INFO [04-09|16:47:08] Commit new mining work                   number=16 txs=0 uncles=0 elapsed=177.032µs
INFO [04-09|16:47:08] Submitted transaction                    fullhash=0x188d17d0ffdbd6ce41e2ca4a37b0e4ae01b909aa148417e48c960d38bd12cd6d recipient=0x7b8D3F0CE869c8fFBFAfF027a7a21fAB6F0e179c
INFO [04-09|16:47:08] Successfully sealed new block            number=16 hash=cfb2b3…b8a7fe
INFO [04-09|16:47:08] 🔗 block reached canonical chain          number=11 hash=fd0e4e…3955ff
INFO [04-09|16:47:08] 🔨 mined potential block                  number=16 hash=cfb2b3…b8a7fe
INFO [04-09|16:47:08] Commit new mining work                   number=17 txs=1 uncles=0 elapsed=290.833µs
INFO [04-09|16:47:09] Successfully sealed new block            number=17 hash=159ff9…f3508d

可知:

有交易的區塊分別是:
十一、1三、1五、17

> eth.getBlock(11)
{
  difficulty: 131712,
  extraData: "0xd883010800846765746887676f312e392e338664617277696e",
  gasLimit: 4249054591,
  gasUsed: 269607,
  hash: "0xfd0e4e6be5425ce319155cfcbe793f2e6d3d52b2d23fd07f3ecfd94a363955ff",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",
  mixHash: "0x49a4b5f7caec56999e58755a60227433f29c5c58b0076432d3d62345151de06c",
  nonce: "0x6a24f90831c7d1f1",
  number: 11,
  parentHash: "0xf93cfaec78ecff5cad537060110ec2125950afd420b6ba126eccb1c8812ed290",
  receiptsRoot: "0xa12b62901dd69f911d94598790f5cd56cd691ccebca50198b50ab64d8a6ebf5b",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 1453,
  stateRoot: "0x89cd5db1f0ca7692e47401e957f4dce8ee9e8aaac0a4354493029a9134573aaa",
  timestamp: 1523263623,
  totalDifficulty: 1576384,
  transactions: ["0x751b8cc80859a4c9fa39aa27b6ee2e89fcbe49713ed3f5fb8f788a886878b714"],
  transactionsRoot: "0xe2a4c28a0c2d74022067bb9aec2a0d3c558c12c415032ab1943ec6ad8d991e06",
  uncles: []
}

> eth.getBlock(13)
{
  difficulty: 131840,
  extraData: "0xd883010800846765746887676f312e392e338664617277696e",
  gasLimit: 4240760105,
  gasUsed: 41981,
  hash: "0xc7d419560c21a331d5e5e61a086c49932d4f45f4404208e40fed4af1123bb02a",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",
  mixHash: "0xf8a970b3d32b998083dd3c39e8ccc7b08a31a4b8c784f707981ea89b266038fb",
  nonce: "0x4adb44428e6e46a5",
  number: 13,
  parentHash: "0xe3408acd7715d948e601463d3cb7ce2e233ca3822015a24a2ba2dfe35f076693",
  receiptsRoot: "0x1ced6b6f323a6d3c8854348bf48831c1279e67ba5a942d354b4f865e42da0eb6",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 679,
  stateRoot: "0x11c52848f9358e3c440a29cd704bcee363693a2582680688e21ee2b334aa9c4d",
  timestamp: 1523263625,
  totalDifficulty: 1840000,
  transactions: ["0x4b6ac5acc4b6965a6463db905eb33019d48ff64ccf3e1cf19d6020dbf0d8f2b6"],
  transactionsRoot: "0x99f487f4989fda3411587062d0c0d8b77c8384786ed8611c600f8a8adc878d22",
  uncles: []
}

> eth.getBlock(15)
{
  difficulty: 131968,
  extraData: "0xd883010800846765746887676f312e392e338664617277696e",
  gasLimit: 4232481478,
  gasUsed: 1155362,
  hash: "0xfea615d7f14b9eea5557ee7db714865a662b8f2638303dad31a2b01d1c3d68a2",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",
  mixHash: "0x6d445e0680455e1b426eac12486bd44d48885d47db9fcf9ef3e37d1cfdce6aa5",
  nonce: "0x343cce18fe3e47df",
  number: 15,
  parentHash: "0x940098cd10e8ffd179b11c719896aed6efd518c89bfec83917f9d78faa434280",
  receiptsRoot: "0xe0619e0df84cf66deb0332cdd5b636c360ad4c6b2efa6960206dd16e67ac64fd",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 4929,
  stateRoot: "0xb3ede09e46d4e16d7ac1693fa6ccc7f81d6a5a37160f39b2e6e29dee76ed4175",
  timestamp: 1523263627,
  totalDifficulty: 2103872,
  transactions: ["0xda750feafdb742c16bb56c57beb84a21346cabc847af19faa98c3fddb47c4057"],
  transactionsRoot: "0xec03b0be1484e3cac495ef585ac0e9fd63e662ef466bdc717e0e8c1acdb8fbfb",
  uncles: []
}

> eth.getBlock(17)
{
  difficulty: 132096,
  extraData: "0xd883010800846765746887676f312e392e338664617277696e",
  gasLimit: 4224220643,
  gasUsed: 26981,
  hash: "0x159ff93dc61a32249f7f6c82fd0db65b8b45e33f416a29a047b2368edaf3508d",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",
  mixHash: "0xf5eda18e9417084bc0e8dcee5a1d05d9c5ef37108427d8265ac4000b7efc9261",
  nonce: "0x0c5e1f26c990f4d2",
  number: 17,
  parentHash: "0xcfb2b3cdda47aa0e7cb785f008613424402709ab6bdf759ea644a85af6b8a7fe",
  receiptsRoot: "0xcabd0eff6a0d339c032b7f9cb5a9f8211ab94c1626c698eff51930d07e103a57",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 679,
  stateRoot: "0xa7c3e91886e55c296c8f0f3566bdf7fe37c09ec3e1a9a74c7583a76a18442d9e",
  timestamp: 1523263629,
  totalDifficulty: 2368000,
  transactions: ["0x188d17d0ffdbd6ce41e2ca4a37b0e4ae01b909aa148417e48c960d38bd12cd6d"],
  transactionsRoot: "0x37ae7f0819cc599fc1edd798dccc5298d7aad92314a1e3fce4703e4516ffc9e2",
  uncles: []
}

4筆交易分別是:

> eth.getTransaction('0x751b8cc80859a4c9fa39aa27b6ee2e89fcbe49713ed3f5fb8f788a886878b714')
{
  blockHash: "0xfd0e4e6be5425ce319155cfcbe793f2e6d3d52b2d23fd07f3ecfd94a363955ff",
  blockNumber: 11,
  from: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",
  gas: 6721975,
  gasPrice: 100000000000,
  hash: "0x751b8cc80859a4c9fa39aa27b6ee2e89fcbe49713ed3f5fb8f788a886878b714",
  input: "0x6060604052341561000f57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102db8061005e6000396000f300606060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100a05780638da5cb5b146100c9578063fdacd5761461011e575b600080fd5b341561007257600080fd5b61009e600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610141565b005b34156100ab57600080fd5b6100b3610224565b6040518082815260200191505060405180910390f35b34156100d457600080fd5b6100dc61022a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561012957600080fd5b61013f600480803590602001909190505061024f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415610220578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b151561020b57600080fd5b6102c65a03f1151561021c57600080fd5b5050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102ac57806001819055505b505600a165627a7a723058200d2898098cb3b0615d05013d7ff7cf6e54eaff6b98e66e9e5a864778b9c6c69d0029",
  nonce: 0,
  r: "0xd9bfae2f413b63cb615d423773f6a48c2898f695be6e13060f9fe43af6a33231",
  s: "0x1a3c02f7f90dc7acd2a75f2ff7018fcb92981815fa9b590c9b9e9bc142ccb5b5",
  to: null,
  transactionIndex: 0,
  v: "0x38",
  value: 0
}

> eth.getTransaction('0x4b6ac5acc4b6965a6463db905eb33019d48ff64ccf3e1cf19d6020dbf0d8f2b6')
{
  blockHash: "0xc7d419560c21a331d5e5e61a086c49932d4f45f4404208e40fed4af1123bb02a",
  blockNumber: 13,
  from: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",
  gas: 6721975,
  gasPrice: 100000000000,
  hash: "0x4b6ac5acc4b6965a6463db905eb33019d48ff64ccf3e1cf19d6020dbf0d8f2b6",
  input: "0xfdacd5760000000000000000000000000000000000000000000000000000000000000001",
  nonce: 1,
  r: "0xe8666b647d772228051922ccd2bbec8d6fb1622716e5484e1a500d9b9de98120",
  s: "0x35fbdb3a0a700f7a1cdf793ab5a6643131660dc64bc8d867a267fdd6cf8e1317",
  to: "0x7b8d3f0ce869c8ffbfaff027a7a21fab6f0e179c",
  transactionIndex: 0,
  v: "0x38",
  value: 0
}

> eth.getTransaction('0xda750feafdb742c16bb56c57beb84a21346cabc847af19faa98c3fddb47c4057')
{
  blockHash: "0xfea615d7f14b9eea5557ee7db714865a662b8f2638303dad31a2b01d1c3d68a2",
  blockNumber: 15,
  from: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",
  gas: 6721975,
  gasPrice: 100000000000,
  hash: "0xda750feafdb742c16bb56c57beb84a21346cabc847af19faa98c3fddb47c4057",
  input: "0x60606040526012600260006101000a81548160ff021916908360ff160217905550341561002b57600080fd5b604051610fed380380610fed83398101604052808051906020019091908051820191906020018051820191905050600260009054906101000a900460ff1660ff16600a0a8302600381905550600354600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600090805190602001906100d39291906100f3565b5080600190805190602001906100ea9291906100f3565b50505050610198565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061013457805160ff1916838001178555610162565b82800160010185558215610162579182015b82811115610161578251825591602001919060010190610146565b5b50905061016f9190610173565b5090565b61019591905b80821115610191576000816000905550600101610179565b5090565b90565b610e46806101a76000396000f3006060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b4578063095ea7b31461014257806318160ddd1461019c57806323b872dd146101c5578063313ce5671461023e57806342966c681461026d57806370a08231146102a857806379cc6790146102f557806395d89b411461034f578063a9059cbb146103dd578063dd62ed3e1461041f575b600080fd5b34156100bf57600080fd5b6100c761048b565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101075780820151818401526020810190506100ec565b50505050905090810190601f1680156101345780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561014d57600080fd5b610182600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610529565b604051808215151515815260200191505060405180910390f35b34156101a757600080fd5b6101af6105b6565b6040518082815260200191505060405180910390f35b34156101d057600080fd5b610224600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506105bc565b604051808215151515815260200191505060405180910390f35b341561024957600080fd5b6102516106e9565b604051808260ff1660ff16815260200191505060405180910390f35b341561027857600080fd5b61028e60048080359060200190919050506106fc565b604051808215151515815260200191505060405180910390f35b34156102b357600080fd5b6102df600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610800565b6040518082815260200191505060405180910390f35b341561030057600080fd5b610335600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610818565b604051808215151515815260200191505060405180910390f35b341561035a57600080fd5b610362610a32565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103a2578082015181840152602081019050610387565b50505050905090810190601f1680156103cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103e857600080fd5b61041d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610ad0565b005b341561042a57600080fd5b610475600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610adf565b6040518082815260200191505060405180910390f35b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105215780601f106104f657610100808354040283529160200191610521565b820191906000526020600020905b81548152906001019060200180831161050457829003601f168201915b505050505081565b600081600560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001905092915050565b60035481565b6000600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561064957600080fd5b81600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506106de848484610b04565b600190509392505050565b600260009054906101000a900460ff1681565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561074c57600080fd5b81600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816003600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a260019050919050565b60046020528060005260406000206000915090505481565b600081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561086857600080fd5b600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482111515156108f357600080fd5b81600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816003600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a26001905092915050565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610ac85780601f10610a9d57610100808354040283529160200191610ac8565b820191906000526020600020905b815481529060010190602001808311610aab57829003601f168201915b505050505081565b610adb338383610b04565b5050565b6005602052816000526040600020602052806000526040600020600091509150505481565b6000808373ffffffffffffffffffffffffffffffffffffffff1614151515610b2b57600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610b7957600080fd5b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401111515610c0757600080fd5b600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401905081600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a380600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401141515610e1457fe5b505050505600a165627a7a7230582058fcacc120960c2cf4be32f0b37a1e0be3601914de2acfb57bad06edc4e9f1ed00290000000000000000000000000000000000000000000000000000000077359400000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000006e582bbe5b881000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025342000000000000000000000000000000000000000000000000000000000000",
  nonce: 2,
  r: "0xbd3c155041f1385edb2b6321083c43421ceb2ed7129c52ac72693529852ae59f",
  s: "0x73a4c275d28a8c87e710bdd571865054ada56e78c5c65541979da4cc619a097d",
  to: null,
  transactionIndex: 0,
  v: "0x37",
  value: 0
}

> eth.getTransaction('0x188d17d0ffdbd6ce41e2ca4a37b0e4ae01b909aa148417e48c960d38bd12cd6d')
{
  blockHash: "0x159ff93dc61a32249f7f6c82fd0db65b8b45e33f416a29a047b2368edaf3508d",
  blockNumber: 17,
  from: "0xad30387c05b527a85f45186c2b8aab5e1af2f227",
  gas: 6721975,
  gasPrice: 100000000000,
  hash: "0x188d17d0ffdbd6ce41e2ca4a37b0e4ae01b909aa148417e48c960d38bd12cd6d",
  input: "0xfdacd5760000000000000000000000000000000000000000000000000000000000000002",
  nonce: 3,
  r: "0x97fbfded3651e150969343f31ac081bc08278c3a2d2c76f70881278f7334b8a0",
  s: "0x2d9a40b70557928d2abe0256f53ce97068db18c4198923e78e550e5f6f1a282e",
  to: "0x7b8d3f0ce869c8ffbfaff027a7a21fab6f0e179c",
  transactionIndex: 0,
  v: "0x38",
  value: 0
}

to爲空的兩筆交易是2個合約的實際部署。\
to不爲空的兩筆交易是更改Migration合約的狀態,是消息調用類型的交易。

部署完成後,如今這個礦工帳戶0xad30387c05b527a85f45186c2b8aab5e1af2f227裏就有2億億SB(這裏單位是wei,注意token也是使用的wei,能夠轉換成ether單位展現)了。爲何是礦工帳戶?由於是TokenSB構造函數裏這句話決定的:

balanceOf[msg.sender] = totalSupply;

構造函數的建立是由礦工0xad30387c05b527a85f45186c2b8aab5e1af2f227完成的,即msg.sender當時是礦工,這個構造函數只執行一次。

交易在黃皮書裏的定義就是一個狀態轉換函數,咱們分析這個狀態轉換函數究竟作了些什麼事情。

一、建立一個外部帳戶\
personal.newAccount('passwd'),即生成一個公鑰私鑰對。

二、「合約建立」

建立一個合約帳戶時使用了不少內在參數:(先不解釋了,之後再說)\

sender (s), \
original transactor (o), \
available gas (g), \
gas price (p), \
endowment (v) \
i\
stack (e)

a ≡ B96..255(KEC(RLP((s, σ[s]n − 1))))

合約帳戶的地址是:僅由建立合約的sender和其nonce構成的RLP編碼的Keccak Hash的右起160位。這裏的96…255是說KEC的hash值會在這個位數範圍內,也即地址位數。\
而之因此是nonce-1,是由於公式裏用的是sender當前的nonce,而建立合約帳戶時的nonce必定是小1的。

運行項目

在truffle工程目錄下執行

npm run dev

常見問題

領養的時候實際是發送交易,調用了eth_sendRawTransaction api。

Error: [ethjs-rpc] rpc error with payload {"id":7299823052815,"jsonrpc":"2.0","params":["0xf88605843b9aca0082f65a94c069c6502457c854f669746861712141ad81414080a48588b2c5000000000000000000000000000000000000000000000000000000000000000025a05ca4a04ef943c9383776ee4c39d6479ac739d470571dcfc842ef0bcfe3ec5f999f6b8966b830b7f0e03cd15c3dd660cd19fe5550196084519eed5a20c8880743"],"method":"eth_sendRawTransaction"} Error: invalid sender

解決答案是:truffle.js的network_id和genesis的chainId須要同樣。

Solidity

IDE語法支持

  • 在IDE裏安裝soldity插件用於支持語法高亮。IDEA系列IDE直接搜索solidity安裝。
  • Atom的插件安裝,在Atom啓動的狀況下,使用命令安裝:

    apm install linter
    apm install linter-solidity

編譯器安裝方式

  • 在本地安裝solcjs這個solidity編譯器(這種安裝方式最簡單)

    能夠在js裏引用模塊、寫編譯方法,執行js對solidity編譯。

    cnpm i -g solc

    也能夠在控制檯編譯.sol文件,使用

    solcjs --abi xxx.sol
  • 或者mac上安裝本地編譯器(這種安裝方式最費勁),編譯器集成在solidity包裏。

    brew update
    brew upgrade
    brew tap ethereum/ethereum
    brew install solidity
    brew linkapps solidity

    設好solidity/bin環境變量後,控制檯編譯使用

    solc --abi -o solcoutput xxx.sol
注意:geth1.6.0以後就再也不集成solc了,因此geth控制檯裏已沒法再編譯合約。

web3

web3是一個js庫,在js應用中能夠經過以太坊節點提供的http RPC接口與以太坊節點交互。

https://github.com/ethereum/w...

geth --rpc

這個geth命令就是啓用了HTTP JSON-RPC(go版節點默認rpc端口是8545,還能夠用--rpccorsdomain設置跨域)。

下面是geth console裏啓用rpc的方法:

admin.startRPC(addr, port)

下面這些方法都有一個額外的默認參數block

  • eth_getBalance
  • eth_getCode
  • eth_getTransactionCount
  • eth_getStorageAt
  • eth_call

參數block能夠取值{

  • HEX String - an integer block number
  • String "earliest" for the earliest/genesis block
  • String "latest" - for the latest mined block
  • String "pending" - for the pending state/transactions

}

web3接口能夠批量請求,批量請求並不會更快,而主要是確保請求的串行處理。

項目是經過web3.js與以太坊進行交互的,好比經過web3對象獲取當前玩家的以太坊帳戶並進行交易。

$.getJSON('TokenSB.json', function (data) {
          var TokenArtifact = data;
          App.contracts.Token = TruffleContract(TokenArtifact);
          App.contracts.Token.setProvider(App.web3Provider);
      })

web3初始化

// 這裏是判斷否已存在web3,好比,若是是用戶登陸MetaMask鏈接到本網絡,則web3是MetaMask的web3。
// MetaMask建立的帳戶由MetaMask維護,而導入的帳戶則每次登陸MetaMask都須要從新導入。
// 不然就建立一個web3,這就可能須要自行實現錢包讓用戶登陸了。
if (typeof web3 !== 'undefined') {
    App.web3Provider = web3.currentProvider;
} else {
    App.web3Provider = new web3.providers.HttpProvider('http://localhost:8545');
}

LevelDB

LevelDB只能被一個進程佔用,當私鏈啓用的時候,其餘進程是不能訪問的,好比LevelDB的某種客戶端。

能夠用如下工具訪問本地LevelDB:
https://github.com/liderman/l...
前提是結束私鏈運行。

以太坊的數據庫經過源碼可知:LevelDB實例加載的是$datadir/geth/chaindata這個目錄。

相關文章
相關標籤/搜索