建议和反馈

请填写你的反馈内容

go 在Uniswap 本地测试和节点部署

2020-11-16 ·948次阅读 ·读完需要6分钟


前段时段用 remix 部署 uniswap,步骤挺繁琐而且 remix 占用内存较大,很容易崩溃,并且不能自动化部署,网上 js 调用合约的很多,go 的却很少,自己动手写了一个当练手了。

Go 的优势

  • 本地可构造链,不需要找水龙头获取测试币

  • 无需找 RPC 节点

  • debug 测试方便,其实也很挺麻烦的

编译 sol 生成 Go 文件可能麻烦点

部署流程

总共需要发起 6 笔合约交易。

  • 部署 WETH 合约

  • 代币合约

  • Uniswap 工厂合约

  • Uniswap RouterV2 合约

  • 代币合约授予 Approve 路由 RouterV2 转移代币权限

  • RouterV2 合约调用 AddLiquidityETH 添加 代币 流动性

准备工作

ABI 和合约字节码 BINCODE

合约部署的时候需要 bincode,有了 bincode 合约当发生合约调用的时候,evm 就知道如何执行,根据 input 中的参数去 abi 中转换成函数和参数,执行相应的调用。abi 的作用是可以把二进制转换成函数参数。可参考 input 解析

合约对应的 bincode 和 abi,这个可用 solcjs 编译和 remix 上获取,我 从uniswap 官网下的代码编译后获取了 abi 和 bincode

这里有个坑,createPair 的时候需要 Pair 合约的·bincode 的 hash 做计算,如果自己编译的话一定要把 sol 源码的值改了

   // calculates the CREATE2 address for a pair without making any external calls
   function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) {
       (address token0, address token1) = sortTokens(tokenA, tokenB);
       pair = address(uint(keccak256(abi.encodePacked(
               hex'ff',
               factory,
               keccak256(abi.encodePacked(token0, token1)),
               hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash
           ))));
   }

每个合约相应的 GO 文件

将 abi 和 bincode 转为相应的 Go 文件,指定 bin 和 abi 分别生成合约部署和合约调用的方法,这个主要是省下自己组装 input

abigen --bin=token_sol_ERCToken.bin --abi=token_sol_ERCToken.abi --pkg=token --out=Token.go

构造交易

交易中重要的概念

  • gas 可以通过 SuggestGasPrice 获取

  • gasLimit 可以通过 EstimateGas 通过模拟执行多次获取平均值

  • chainId 可通过 eth_chainId 方法获取

  • nonce 通过如下获取 PendingNonceAt 这种在同一高度同一账户下多笔会有问题

  • input 可自己拼装或用生成的 go 文件方法

按上面流程组装的交易,成功率应该很高。

本地测试

本地测试需要节点模拟器,就是构造一条区块链,transactOpts 是封装私钥的结构体包含转账金额的一些设置。

   contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{
   	addr:     {Balance: new(big.Int).SetUint64(10000000000000000000)},
   	testAddr: {Balance: big.NewInt(100000000000000)}},
   	100000000)
   transactOpts := bind.NewKeyedTransactor(key)

每当有交易的时候调用 commit 打包交易。

contractBackend.Commit()

通过测试用例测试,很容易就可拿到执行结果。可参考代码 TestDeployUniswapLocal 设置这个变量可以获取合约执行过程的日志
backends.SimulateDebug = true

节点部署

节点部署比上面麻烦一点,有如下几点

  • 合约有执行失败的可能,同一高度多笔交易 nonce 需要统一管理

  • 交易上链时间不确定,需要持续获取交易状态

  • 需要最新高度的发交易节点

刚开始的 没注意 到 模拟器 和 rpc返回的连接 都实现了这个接口 backend bind.ContractBackendbackend bind.ContractBackend 这个测试用例里面是本地部署成功后,获取交易的 Input 自己在组装发交易。后面发现接口一样,重新实现了 TestDeployUniswapRPC,这个屏蔽了一些技术细节,只需要调生成的接口即可。

代码讲解

这个主要是获取连接,输出一些节点的基本信息。

	url := "http://157.245.118.249:8545"
	client, url := dialConn(url)
	printBaseInfo(client, url)
	PrintBalance(client, addr)

部署 eth 工厂 代币合约,这两个没有顺序要求,可在同一块打包。

	_, wtx, _, err := weth.DeployTokene(transactOpts, client)
	_, ftx, _, err := factory.DeployTokenf(transactOpts, client, addr)
	_, mtx, _, err := cdc.DeployTokenc(transactOpts, client)

getResult 方法首先查询交易是否在 pengding 状态,当交易不是 pengding 后查询收据 Receipt,当 receipt.Status == types.ReceiptStatusSuccessful 时交易成功。

_, isPending, err := conn.TransactionByHash(context.Background(), txHash)		if err != nil {
			fatallog.Fatal(err)			return false, common.Address{}
		}
			receipt, err := conn.TransactionReceipt(context.Background(), txHash)	if err != nil {
		fatallog.Fatal(err)
	}

当上面各个交易成功后,部署 Router 交易需要 工厂 和 weth 的合约地址,成功后代币合约部署者授予 Router 代币的转账权限,对方可调用 transaferFrom 转移代币。

	_, routerTx, _, err := DeployToken(transactOpts, client, facR, wethR)
	result, routerAddr := getResult(client, routerTx.Hash())	if !result {
		fatallog.Fatal("sendBaseContract routerTx", err)		return
	}

	mapTran, err := cdc.NewTokenc(mapTR, client)
	atx, err := mapTran.Approve(transactOpts, routerAddr, new(big.Int).SetUint64(1000000000000000000))
	result, _ = getResult(client, atx.Hash())	if !result {
		fatallog.Fatal("sendBaseContract atx", err)		return
	}

有了合约授权,添加流动性转移以太坊获取代币。

	tik := new(big.Int).SetUint64(10000000000000000)
	tik1 := new(big.Int).SetUint64(1000000000000)
	transactOpts.Value = new(big.Int).SetUint64(1000000000000000000)
	RTran, err := NewToken(routerAddr, client)
	aHash, _ := RTran.AddLiquidityETH(transactOpts, mapTR, tik, tik, tik1, addr, new(big.Int).SetUint64(1699658290))
	result, _ = getResult(client, aHash.Hash())

以太坊确定较慢,部署需要等待一两分钟可结束。
部署结果已上链,可查阅
github 链接 欢迎 star


声明:作为区块链技术信息平台,本站所提供的资讯信息不代表任何投资暗示,本站所发布文章仅代表个人观点,与链客社区官方立场无关。
评论(0)问答(0)
请先登录或注册

请先登陆或注册

相关推荐

至臻说币:比特币的价格会影响DeFi吗?关于DeFi和区块链的2021年预测

或许你会听到这样的消息:比特币(BTC)正在掠夺其历史最高价。在撰写本文时,BTC的每枚硬币徘徊在16400美元左右,朝着2017年12月的20,000美元前进,随后发生了壮观的崩盘,一年后又跌至4,......
至臻说币 · 2020-11-28
1072阅读 · 0赞赏 · 0问答

过招DEFI合约审计

DeFi项目正式部署前,通过合约的安全审计,不仅可以对项目的代码规范、漏洞情况以及业务逻辑等方面进行全局核查。同时,项目审计对于项目方在投资市场的形象也具有一定塑造作用。![](https:...De......
Cristante · 2020-11-20
901阅读 · 0赞赏 · 0问答

奖励升级,SANDWICH节点招募火热

近日,SANDWICH向全球发布节点招募计划并升级了推荐奖励,推荐节点最高获得75%的节点等额收益。所有参与了sandwich节点建设的用户都可以获得SWH、Sandwich社区建设的投票发起权和永久......
牛肉三明治 · 2020-11-18
475阅读 · 0赞赏 · 0问答

Uniswap流动性挖矿暂停后的何去何从

根据原计划,在北京时间11月17日8点,领先的去中心化交易所Uniswap将结束其初始流动性挖矿计划,这可能会造成部分Uniswap流动性资金的流失。据悉,截至目前,Uniswap协议锁定的加密资产达......
月花雾 · 2020-11-16
752阅读 · 0赞赏 · 0问答

知名白帽 Sam Sun 撰文详述 DeFi 为何频发价格预言机操纵攻击

2019 年末,我发表了一篇题为《从抵押不足贷款取乐并牟利》 (Taking undercollateralized loans for fun and for profit) 的帖子。我在文中描述了......
YYF · 2020-11-16
751阅读 · 0赞赏 · 0问答

justnow

4558.0

LK币

3

粉丝

51

笔记

感谢"justnow"

这篇精彩的笔记,目前已经帮助

  • 0
  • 0
  • 9
  • 4
  • 8
喜欢0
链客社群 加入

微博进入

商务合作>

广告投放>

公司名称:北京链客行科技有限公司

联系方式:010-67707199

ICP备案号:京ICP备18032136号

Copyright:链客区块链技术问答社区 版权所有

感谢您的提问,问题被社区永久收入以便新人查看。一定要记得采纳最佳答案哦!加油!

感谢您的善举,每一次解答会成为新人的灯塔,回答被采纳后获得20算力和相应的LK币奖励

您将赞赏给对方2LK币的奖励哦!感谢您的赞赏!

您将赞赏给对方2LK币的奖励哦!感谢您的赞赏!