本節,將具體記錄使用go語言,在以太坊搭建的私鏈環境下,進行區塊操作和智能合約的互動、開發等等
前提閱讀
- 搭建以太坊私鏈記錄
環境準備
依賴包
需要下載依賴:
$ go get -d github.com/ethereum/go-ethereum/...
安裝abigen
go直接和智能合約互動,有很多瑣碎的細節需要照顧到,比較麻煩.以太坊專門為我們提供了一個abigen的工具,他可以根據sol或者abi檔案生成特定語言的封裝,方便進行互動,支持golang,objc,java三種語言,
一般的,我們安裝solc和安裝abigen工具是一起進行的,
安裝solc:
直接在官網https://github.com/ethereum/solidity/releases
下載二進制檔案即可
安裝abigen
對源檔案進行編譯:
$ cd $GOPATH/src/github.com/ethereum/go-ethereum
$ make abigen
就可以形成以下的二進制檔案:
root@cchui-virtual-machine:~/eth/go-ethereum/build/bin# ls
abidump abigen bootnode checkpoint-admin clef devp2p ethkey evm faucet geth
其中,abigen和geth就是我們想要的了,
之后,配置到環境變數中,
使用命令:
abigen -sol ./Hello.sol -pkg contract -out ./Hello.go
即可編譯成go代碼的智能合約,
部署合約
啟動
啟動以如下命令啟動,開啟http,rpc,wc等服務:
geth --identity "test Chain" --datadir ./datachain --rpc --rpcport 8547 --ws --ws.port=8546 --http.port=8548 --rpccorsdomain "*" --port 1718 --nodiscover --nat "any" --networkid 10 --rpcapi "eth,net,web3,personal" console --allow-insecure-unlock
之后,可能在解鎖賬戶的時候報錯:
error:account unlock with HTTP access is forbidden
這是由于新版本geth,出于安全考慮,默認禁止了HTTP通道解鎖賬戶
解決方式:啟動節點命令添加--allow-insecure-unlock,
撰寫智能合約:
pragma solidity >=0.8.6;
contract Hello {
string name = "hello CC";
function set(string memory _name) public{
name = _name;
}
function get() public view returns(string memory){
return name;
}
}
這里需要注意,我使用的版本abigen,只支持soldity 在0.8.6+版本上編譯,
部署合約
根據官網:
// const key = "account/UTC--2021-07-26T12-39-54.784952954Z--471144a5fec2d48450d6e14438a448be839dcd04"
const key = `
{
"address": "471144a5fec2d48450d6e14438a448be839dcd04",
"crypto": {
"cipher": "aes-128-ctr",
"ciphertext": "df39a477f35ecbd138c78da5d4968e69388b287bbddba9403fb4298b1a3a156a",
"cipherparams": {
"iv": "2e57aeb78f37fd7dd3f127c483d6c457"
},
"kdf": "scrypt",
"kdfparams": {
"dklen": 32,
"n": 262144,
"p": 1,
"r": 8,
"salt": "8581cd5b79c791866d3707444b5d8e5fd3fed29da9b20e7409be8d1fc41603b4"
},
"mac": "036e4d384c714a0ffdfc418f5703bc00c731b5134e339356a3a7ebc38022fec3"
},
"id": "f69bdc60-d5d5-4ec9-a9d2-b2f30be8de1a",
"version": 3
}
`
func Deploy() {
// 連接到以太坊智能合約
conn, err := ethclient.Dial("http://127.0.0.1:8548")
if err != nil {
log.Fatalf("Failed to connect to the Ethereum client: %v", err)
}
auth, err := bind.NewTransactorWithChainID(strings.NewReader(key),
"123456", big.NewInt(15))
if err != nil {
log.Fatalf("Failed to create authorized transactor: %v", err)
}
// 部署一個合約
address, tx, hello, err := contract.DeployHello(auth, conn)
if err != nil {
log.Fatalf("Failed to deploy new token contract: %v", err)
}
fmt.Printf("Contract pending deploy: 0x%x\n", address)
fmt.Printf("Transaction waiting to be mined: 0x%x\n\n", tx.Hash())
time.Sleep(250 * time.Millisecond)
}
這里需要注意:NewTransactor方法已經棄用了,詳情參考:bind · pkg.go.dev
這里,我遇到了一個問題:
error "invalid character 'a' looking for beginning of value” from json.Unmarsh
這是由于不能正確決議json導致的,嘗試了很多辦法都不行,最后只能把json 里的資料,寫到變數里去了,
還可能遇到一個問題:
Returned error: invalid sender
這是由于初始化鏈的chainId和啟動引數networkId,或者與NewTransactorWithChainID引數輸入的ChainID不一致導致的,
改變好chainId一致即可,
最后,終于是部署成功了:
> miner.start(1)
INFO [07-30|20:08:46.709] Updated mining threads threads=1
INFO [07-30|20:08:46.709] Transaction pool price threshold updated price=1,000,000,000
INFO [07-30|20:08:46.710] Commit new mining work number=76 sealhash=114b38..8ef0ab uncles=0 txs=0 gas=0 fees=0 elapsed="93.219μs"
INFO [07-30|20:08:51.192] Setting new local account address=0x471144A5FEC2d48450d6e14438a448Be839DCd04
INFO [07-30|20:08:51.192] Submitted contract creation hash=0xce9b306e0749d5607da00f62fa04157df489f8c450b437150ca380a1ffc50ce0 from=0x471144A5FEC2d48450d6e14438a448Be839DCd04 nonce=0 contract=0xd9D695DecfC653A4F48D6910bA653De1B777d936 value=0
INFO [07-30|20:08:52.711] Commit new mining work number=76 sealhash=c62671..ee1882 uncles=0 txs=1 gas=257,245 fees=0.000257245 elapsed="331.346μs"
INFO [07-30|20:08:53.314] Successfully sealed new block number=76 sealhash=c62671..ee1882 hash=a49383..bdadae elapsed=603.333ms
INFO [07-30|20:08:53.314] 🔨 mined potential block number=76 hash=a49383..bdadae
INFO [07-30|20:08:53.315] Commit new mining work number=77 sealhash=f85627..c5b5af uncles=0 txs=0 gas=0 fees=0 elapsed="191.813μs"
得到合約地址:
Contract pending deploy: 0xd9d695decfc653a4f48d6910ba653de1b777d936
Transaction waiting to be mined: 0xce9b306e0749d5607da00f62fa04157df489f8c450b437150ca380a1ffc50ce0
查詢
測驗查詢:
func GetName() {
// 連接到以太坊節點
conn, err := ethclient.Dial("http://127.0.0.1:8548")
if err != nil {
log.Fatalf("Failed to connect to the Ethereum client: %v", err)
}
// 初始化合約,輸入地址
token, err := contract.NewHello(common.HexToAddress("0xd9d695decfc653a4f48d6910ba653de1b777d936"), conn)
if err != nil {
log.Fatalf("Failed to instantiate a Token contract: %v", err)
}
name, err := token.Get(nil)
if err != nil {
log.Fatalf("Failed to retrieve token name: %v", err)
}
fmt.Println("name is:", name)
}
參考
-
Go API | Go Ethereum
-
安裝Solidity編譯器
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/291256.html
標籤:區塊鏈
上一篇:搭建以太坊私鏈記錄
