栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 前沿技术 > 区块链 > 其他

Go开发以太坊私链

其他 更新时间:发布时间: 百科书网 趣学号

本节,将具体记录使用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%xn", address)
	fmt.Printf("Transaction waiting to be mined: 0x%xnn", 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编译器

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/848404.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号