单公证人模式实现测试链间跨链【入门教程(下)】

2024-02-04 08:10

本文主要是介绍单公证人模式实现测试链间跨链【入门教程(下)】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

3.5监听区块链部分代码

监听器用的是web3.js 文件,使用VS Code编码

下面代码中存在的abi文件需要自己去复制合约的abi字节码,复制后在vs中建立一个xxx.abi文件,将内容粘贴进去即可,如果是在同个文件夹内使用我这种路径方式即可,实在不行就写绝对路径吧。
在这里插入图片描述
使用subscribe监听事件,并发送交易

var Web3 = require("web3");
const {Transaction: Tx, Transaction} = require("ethereumjs-tx");
var fs = require('fs');// fs模块读取.sol合约文件var  privateKey = Buffer.from("2bc4b12344dcd517c48f7eba2e5b5d0c206c6a124d7fd938f392a881785a4021",'hex');// 私钥
var  fromAddress = "0x6123493654b3E23D9007e56EE7131b6dd305dfDd"; //账户地址//---------------------------------------
//-------Ropsten测试网配置----------------
var ropsten_wssurl = "wss://ropsten.infura.io/ws/v3/99b7804fba9a484f8afd1fac5bc75cdf"; 
// 如果报错Error: Transaction has been reverted by the EVM 可能是vpn出问题了,检查网络
// chainid=3  如果报错Error: connection not open on send()  换个infura节点即可var ropsten_web3 = new Web3(new Web3.providers.WebsocketProvider(ropsten_wssurl));
var ropsten_ABI = JSON.parse(fs.readFileSync("ropsten_bridge.abi").toString());
var ropsten_contract_address = '0x173EB118FA344f9D1E2f9b3cB94F4E650D6637B5';//ropsten的跨链桥地址***
//               NATIVE_RETH = 0x4a03c24614a251a1b75c4ccCC5b3bE7b542f716f
//                ERC20_BETH = 0x0392Ae4b926ABf4abDDE26e9E02103d9ac4E6275
var ropsten_contract = new ropsten_web3.eth.Contract(ropsten_ABI,ropsten_contract_address);//---------------------------------------
//-------Rinkeby测试网配置----------------
var rinkeby_wssurl = "wss://rinkeby.infura.io/ws/v3/99b7804fba9a484f8afd1fac5bc75cdf"; 
var rinkeby_web3 = new Web3(new Web3.providers.WebsocketProvider(rinkeby_wssurl));
var rinkeby_ABI = JSON.parse(fs.readFileSync("rinkeby_bridge.abi").toString());
var rinkeby_contract_address = '0x729eC6Df5470099AADfa1ebD770722b45393cC7A';//rinkeby的跨链桥地址***
//               NATIVE_BETH = 0x988b22b8502eC4443dC2a0D5DbbbdB85aBcE3b47
//                ERC20_RETH = 0x94F8fF14EE6D4fbB90750fF4E6630080Cbc29b5d
var rinkeby_contract = new rinkeby_web3.eth.Contract(rinkeby_ABI,rinkeby_contract_address); console.log('ropsten_bridge subscription start');
ropsten_web3.eth.subscribe('logs', {address: ropsten_contract_address,topics:['0x4db14528ca520835e36decc6d6140e6cefbd849bedda8745497406a62317c80d'] //********这里记得换成监听事件的十六进制}, function(error, result){if (!error)console.log('this is ropsten_subcription');info=ropsten_web3.eth.abi.decodeLog([{ // 解析日志内容type: 'address',name: 'token'},{type:'string',name:'symbol'},{type:'uint',name:'fromChainID'},{type:'address',name:'from'},{type:'uint',name:'toChainID'},{type:'address',name:'toAddress'},{type:'uint',name:'amount'}],result.data,result.topics);{ // 获取log的信息SYMBOL = info[1];TO_CHAINID = info[4];TO = info[5];VALUE = info[6];}if(TO_CHAINID == 4){//跨到rinkeby,使用rinkeby_web3往rinkeby发交易var DATA=rinkeby_contract.methods.receipt(SYMBOL,TO,VALUE).encodeABI(); rinkeby_web3.eth.getTransactionCount(fromAddress, rinkeby_web3.eth.defaultBlock.pending).then(function(nonce){var rawTx={nonce: rinkeby_web3.utils.toHex(nonce++),gasLimit: rinkeby_web3.utils.toHex(99000),gasPrice: rinkeby_web3.utils.toHex(10e9), // 10 Gweito: rinkeby_contract_address,//目标合约地址from: fromAddress, //privateChain_data: DATA // thanks @abel30567}var tx=new Tx(rawTx,{chain:'rinkeby'});// 如果说invalid account ,在tx后面加连的名称 tx.sign(privateKey);var serializedTx = tx.serialize();console.log('will send transaction');rinkeby_web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')).on('receipt', console.log);console.log('had been sent transaction');})   }}
)console.log('rinkeby_bridge subscription start');
rinkeby_web3.eth.subscribe('logs', {address: rinkeby_contract_address,//监听rinkeby链上的合约地址的事件topics:['0x4db14528ca520835e36decc6d6140e6cefbd849bedda8745497406a62317c80d'] //********这里记得换}, function(error, result){if (!error)console.log('this is rinkeby_subcription');info=rinkeby_web3.eth.abi.decodeLog([{ // 解析日志内容type: 'address',name: 'token'},{type:'string',name:'symbol'},{type:'uint',name:'fromChainID'},{type:'address',name:'from'},{type:'uint',name:'toChainID'},{type:'address',name:'toAddress'},{type:'uint',name:'amount'}],result.data,result.topics);{ // 获取log的信息SYMBOL = info[1];TO_CHAINID = info[4];TO = info[5];VALUE = info[6];}if(TO_CHAINID == 3){//跨到ropsten,使用ropsten_web3往ropsten发交易var DATA=ropsten_contract.methods.receipt(SYMBOL,TO,VALUE).encodeABI(); ropsten_web3.eth.getTransactionCount(fromAddress, ropsten_web3.eth.defaultBlock.pending).then(function(nonce){var rawTx={nonce: ropsten_web3.utils.toHex(nonce++),gasLimit: ropsten_web3.utils.toHex(99000),gasPrice: ropsten_web3.utils.toHex(10e9), // 10 Gweito: ropsten_contract_address,//目标合约地址from: fromAddress, //privateChain_data: DATA // thanks @abel30567}var tx=new Tx(rawTx,{chain:'ropsten'});// 如果说invalid account ,在tx后面加连的名称 tx.sign(privateKey);var serializedTx = tx.serialize();console.log('will send transaction');ropsten_web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')).on('receipt', console.log);console.log('had been sent transaction');})   }}
)

3.6 智能合约、监听 初始化 设置

3.6.1 钱包与编译器连接

使用小狐狸钱包,点开左上角连接按钮,将钱包与Remix编译器进行连接。并选择实验所需连接的区块链。接下来会在两个区块链间反复切换,我会在图片中表明当前环境所处区块链。
在这里插入图片描述
在这里插入图片描述

接着点击Remix编译器左侧,选择injected web3,连接我们的环境。
在这里插入图片描述
在这里插入图片描述

可以发现已经连上了我们的区块链并且使用我们的区块链账户。
我们做的系统是跨链交易所,此处假设为两条链之间进行跨链资产转移,那么A链的原生代币跨链到B链时就变成了B链的ERC20代币,因此我们这个过程中每条链需要用到三个合约——原生代币管理合约、ERC20合约(可通用化)、跨链桥合约。

3.6.2 在Ropsten上部署并初始化合约

(1)部署并初始化跨链桥合约
选择部署合约的账户(user2),部署合约时输入该链对应的原生代币。此链为Ropsten,因此原生代币为RETH。
在这里插入图片描述

成功部署后可以获得该合约的地址,右侧可以复制合约地址

在这里插入图片描述

(2)部署并初始化原生代币合约(为了区分父子合约地址,部署代币合约使用的地址为uesr3)
为合约初始化,输入父合约的地址——跨链桥地址
在这里插入图片描述

(3)部署并初始化ERC20合约(此处仍使用uesr3账号部署合约)
输入初始化总代币数量(此处用于测试存取款功能),输入父合约地址——跨链桥地址,点击transact部署合约
在这里插入图片描述

(4)往跨链合约添加代币合约地址
在代币合约部署前我们无法知晓代币合约地址,因此我们需要在代币合约部署完成后将地址写入到跨链合约中。
我们部署原生代币RETH的合约:输入原生代币名称——RETH,再把刚刚部署完成的合约地址复制粘贴过来,点击transact提交交易。
同样的,部署BETH代币(BETH为Rinkeby链的原生代币,跨链的话则在Ropsten链上创造一种与之等价的ERC20代币,此处也称之为BERH)的操作也是如此。

注意:此操作并非任何人都可以随意操作,因此合约中设置为只有合约创建者才可调用此函数,此合约创建者为user2,故需要点击小狐狸钱包将账户切换至user2。
在这里插入图片描述
在这里插入图片描述

调用跨链合约中的ERC20_CIBTRACT函数查看是否添加合约地址成功。

在这里插入图片描述
在这里插入图片描述

3.6.3 在Rinkeby上部署并初始化合约

Rinkeby上的合约与Ropsten属于镜像合约,只需要修改几个参数即可***(
①修改跨链桥合约的fromchainID,NAVITVE_CHAINID为本链id;
②将ERC20合约中的name,symbol,decimal更改为对应的ERC20代币即可,此合约修改这几个参数即可 实现通用化;
③将原生代币合约(NAVIVE_ETH.sol)的代币属性修改成改链的原生代币)***。

注意:部署时切换到Rinkeby链,其余部署方式参考Ropsten部署与初始化(1)~(4)。

在这里插入图片描述

3.6.4 监听器初始化设置

设置自己的私钥、发送交易账户地址(私钥与账户地址必须对应):
在这里插入图片描述

连接到区块链,输入要连接区块链的RPC_URL:
在这里插入图片描述
(如果无法连接上,可能节点有问题,可以取infura官网创个账户,他会分配一个节点给你,将那个节点地址粘贴过来即可)

合约实例化:
a)导入合约abi字节码。点击remix编译器左侧箭头处即可复制当前合约的字节码。在在VS编译器(用于编写监听程序)中创建Ropsten_bridge.abi文件,将abi码粘贴过去即完成导入。
在这里插入图片描述

b)输入要监听的合约地址:
在这里插入图片描述
在这里插入图片描述

c)输入要监听的事件的十六进制编号:
在这里插入图片描述
在这里插入图片描述

只要写了event事件,topics可以在remix抛出的logs中找到,如:

在这里插入图片描述

4 跨链实验

合约中的其他功能读者可以自行测试,由于篇幅有限,此处仅示例跨链过程

4.1 Ropsten跨原生代币RETH至Rinkeby

已知跨链交易是在A链锁住代币,在B链释放对应的代币。

(1)在跨链开始前,先启动链下监听器
在这里插入图片描述

(2)首先从Ropsten链将原生代币RETH跨链到Rinkeby中——user3输入跨链币种RETH,目标链4(Rinkeby),目标地址(user3在Rinkeby中的地址),最后输入要跨链金额(右图即0.01eth)
在这里插入图片描述
在这里插入图片描述

(3)在跨链前先查看user3在Ropsten上余额——0.1681RETH
在这里插入图片描述

Rinkeby网络中的RETH余额——10^19Wei(10RETH)
右边钱包可知当前处于rinkeby网络
在这里插入图片描述

(4)记录完跨链前数据,开始跨链:
在这里插入图片描述

(5)跨链成功后,监视器返回发送交易成功的信息
在这里插入图片描述

(6)检查Ropsten链上是否减少了对应的原生代币(少的0.0002RETH用于gas消耗)

在这里插入图片描述

(7)检查目标链上是否增加了等量的ERC20_Ropsten代币(将网络切换到Rinkeby)

在这里插入图片描述

4.2 Rinkeby跨ERC20代币RETH至Ropsten

(1)在Ropsten中,RETH是原生代币,但在Rinkeby中BETH才是原生代币,因此在Rinkeby中RETH为ERC20代币,即RopstenETH在Rinkeby中的等价替代品。由于是ERC20代币,在交易所中进行转账时需要先给交易所提供代理金额
在这里插入图片描述

(2)使用Rinkeby链中的跨链桥中的general_cross_transfer函数进行ERC20资产跨链
在这里插入图片描述

(3)跨链前检查Ropsten中RETH余额
在这里插入图片描述

(4)开始跨链
在这里插入图片描述

(5)跨链成功后,监视器返回发送交易成功的信息

在这里插入图片描述

(6)检查ropsten链是否增加了对应的RETH
在这里插入图片描述

这篇关于单公证人模式实现测试链间跨链【入门教程(下)】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/676847

相关文章

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在