安装准备
其中npm环境我在另一篇文章写过
https://blog.csdn.net/weixin_42608885/article/details/93340253
solidity编辑器
golang版本越新越好
solcjs
npm
solidity编辑器安装
https://blog.csdn.net/weixin_42608885/article/details/95461391
在我的另一篇文章写过,他会默认帮你安装abigen
还有就是solcjs安装我这里是通过npm进行安装的。注意一点:在生成abi的时候solcjs的版本一定要和你合约上方的版本对齐。
不然后面部署会出问题,这个问题浪费了我一天时间。我这里是指定0.5.0的solcjs版本,对应solidity的0.5.0。
sudo npm install -g solc@0.5.0
比如我要安装0.4.24那么就这样写
sudo npm install -g solc@0.4.24
拉取源码,我这里是拉取的quorum的源码,你也可以视情况而定拉取go-ethereum源码也可以,看你们是什么链
git clone https://github.com/jpmorganchase/quorum.git
不管以太坊还是quorum都需要来拉取go-ethereum源码。
go get github.com/ethereum/go-ethereum
这里拉取完毕后就进入源码目录我这里是
cd quorum/
//然后
make all
//完成后他会在当前目录下的build/bin下面生成多个可执行文件,包括geth和abigen
//我们把他拉到环境变量里
sudo cp ./geth /usr/bin
sudo cp ./abigen /usr/bin
智能合约准备
pragma solidity ^0.5.0;
contract pdbank {
address public owner;
mapping(address=>uint256) public balances;// 纪录每个账户余额
uint256 public totalAmount;
string public bankName;// 银⾏行行名称
// 构造函数
constructor(string memory _bankName) public {
owner = msg.sender;
bankName = _bankName;
}
// 充值
function deposit() public payable {
//do nothing
totalAmount += msg.value;
balances[msg.sender] += msg.value;
}
// 提现
function withdraw(uint256 _amount) public payable {
if(balances[msg.sender] > _amount) {
balances[msg.sender] -= _amount;
msg.sender.transfer(_amount);
totalAmount -= _amount;
}
}
}
这个智能合约主要就是银行功能。
编译合约
我们然后进行合约编译,我们使用abigen来生成对应的go文件,这个go文件把合约里的函数做成了go语言版的,我们可以很方便的调用go文件里还包含了abi和bin。另外abigen也可以用来单独生成ABI和BIN。
使用命令生成
abigen -sol pdbank.sol -pkg Pdbank -out Pdbank.go
这里的pdbank.sol 是合约文件名 pdbank 是生成的go文件的包名 pdbank.go是生成的go文件名
部署合约
package main
import (
"github.com/ethereum/go-ethereum/ethclient"
"log"
"fmt"
"os"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"io"
"context"
"github.com/contracts" //这里是我生成的go文件的路径。我在这个文件中导入它
"math/big"
)
func main(){
CallDeploy()
}
func CallDeploy(){
//读取私钥文件内容
keydate:=readkeydate()
//获得与以太坊的连接
//需要注意的是这里不管输入什么IP地址都不会报错。只有在后面做其他操作的时候才会显示报错
cli, err := ethclient.Dial("http://127.0.0.1:22000")
if err != nil {
log.Fatal("连接私链失败:", err)
}
//函数结束自动关闭连接
defer cli.Close()
//这里第一个参数是加密的私钥内容,第二个参数是账户密码。我这里是空
auth,err:=bind.NewTransactor(keydate,"")
//获得一个可以操作账户的签名对象
if err != nil {
log.Fatal("得到账户列表失败:", err)
}
//设置gas,这里必须设置,不设置的话可能报错。
auth.GasLimit=3000000000
//参数分别是:账户所有者的签名,连接句柄,构造函数参数:返回合约地址,交易哈系,合约对象,错误信息
addr,ts,_,err:=pdbank.DeployPdbank(auth,cli,"tongfa")
if err!=nil{
fmt.Println("部署合约失败",err)
}
//这里是显示部署成功的合约地址,转成16进制。
fmt.Println("合约地址:", addr.Hex(), "交易哈希:", ts.Hash().Hex())
}
//读取私钥文件,私钥文件存在本地的话
func readkeydate()(f io.Reader){
f, err := os.Open(`/home/zxc/quorum-maker-master/node1/node/qdata/keystore/node1key`)
if err != nil {
fmt.Println("读取私钥信息失败!")
return nil
}
return f
}
到这里就部署成功了.
我这里保存文件名字为main.go
然后运行
go run mian.go
遇到的坑
这里要说一下部署中遇到的坑,那就是一定要注意合约的版本以及abigen的版本,如果不符合就算部署失败也不会提示错误。而且还会照样返回合约地址以及交易哈希等。只有在真正调用的时候才会报错
no contract code at given address
就像上面这样,提示没有合同代码。
这样的话我们需要找到我这里的pdbank.go文件,找到里面的bin使用正确的bin替换掉它。或者使用相同版本的abigen来重新生成bin,我是用在线编译器Remix获得正确bin来替换的。你也可以用其他工具像是solcjs来生成正确bin来替换,上面我提到过需要安装的。以上工具一定要用对应合约版本
这是一个使用solcjs生成bin的例子
solcjs pdbank.sol --bin
如果以上有什么错误请各位大佬指正