WalletConnect C++开发包

WalletConnect C++开发包完整实现WallectConnect协议,可以为C++应用快速添加对 以太坊等EVM兼容区块链的支持能力。

WalletConnect C++开发包
一键发币: SOL | BNB | ETH | BASE | Blast | ARB | OP | POLYGON | AVAX | FTM | OK

WalletConnect C++开发包完整实现WallectConnect协议,可以为C++应用快速添加对 以太坊等EVM兼容区块链的支持能力,适用于Web3应用开发的学习与实践。下载请联系邮箱: kukapaycrypto#gmail.com

1、概述

WalletConnect C++开发包主要特性如下:

  • 支持以太坊及EVM兼容区块链,例如BSC、Polygon、Fantom等
  • 支持Metamask、imtoken等多种区块链钱包
  • 内置ABI编解码器,支持以太坊及EVM兼容链智能合约的部署、读取及交易
  • 内置ERC20和ERC721规范支持

WalletConnect C++开发包当前版本1.0.0,运行于64位Windows环境,主要类及关系如下图所示:

WalletConnect C++开发包的主要代码文件清单如下:

代码文件说明
WalletConnect/WalletConnect.slnWalletConnect解决方案文件
WalletConnect/WalletConnect/WalletConnect.vcxprojWalletConnect DLL库项目文件
WalletConnect/WalletConnect/WalletConnect.h库入口类C++头文件
WalletConnect/WalletConnect/WalletConnect.cpp库入口类C++实现文件
WalletConnect/WalletConnect/ClientMeta.h客户端元信息C++头文件
WalletConnect/WalletConnect/ClientMeta.cpp客户端元信息C++实现文件
WalletConnect/WalletConnect/Erc20.hERC20合约类C++头文件
WalletConnect/WalletConnect/Erc20.cppERC20合约类C++实现文件
WalletConnect/WalletConnect/Erc721.hERC721合约类C++头文件
WalletConnect/WalletConnect/Erc721.cppERC721合约类C++实现文件
WalletConnect/WalletConnect/Contract.h智能合约类C++头文件
WalletConnect/WalletConnect/Contract.cpp智能合约类C++实现文件
WalletConnect/WalletConnect/EthAbi.hSolidity ABI编解码器类C++头文件
WalletConnect/WalletConnect/EthAbi.cppSolidity ABI编解码器类C++实现文件
WalletConnect/WalletConnect/AbiType.hSolidity ABI数据类型C++头文件
WalletConnect/WalletConnect/AbiType.cppSolidity ABI数据类型C++实现文件
WalletConnect/WalletConnect/JsonRpcClient.hJsonRpc客户端类C++头文件
WalletConnect/WalletConnect/JsonRpcClient.cppJsonRpc客户端类C++实现文件
WalletConnect/WalletConnect/SocketClient.hSocket传输类头C++文件
WalletConnect/WalletConnect/SocketClient.cppSocket传输类C++实现文件
WalletConnect/WalletConnect/CryptoLib.h密码学算法类C++头文件
WalletConnect/WalletConnect/CryptoLib.cpp密码学算法类C++实现文件
WalletConnect/WalletConnect/QrCodeGen.hQR二维码生成器C++头文件
WalletConnect/WalletConnect/QrCodeGen.cppQR二维码生成器C++实现文件
WalletConnect/Demo/Demo.vcxprj演示项目文件
WalletConnect/Demo/Demo.cpp演示代码实现文件
WalletConnect/SmartContract/演示用合约目录

2、使用示例代码

2.1 连接手机钱包

第一次运行Demo演示项目时,将弹出二维码提示扫码连接钱包:

使用MetaMask等手机钱包扫描二维码并确认连接后,可以看到终端显示授权成功:

2.2 原生token的余额查询和转账交易

command> 下输入native,然后按回车,将演示原生token的余额查询和转账交易。

演示程序首先显示所连接手机钱包账户的余额,然后执行一个转账交易:

注意:执行转账时,将在手机钱包弹出提示信息,确认后即可完成交易。如果在手机钱包的提示中选择拒绝, 则终端提示如下:

2.3 部署ERC20合约

command> 下输入deploy erc20,然后按回车,将演示ERC20合约的部署:

注意:合约部署也是交易,因此将在手机钱包弹出提示信息,需确认后才可完成合约部署交易。

2.4 ERC20 token的查询和转账

command> 下输入erc20,然后按回车,将演示ERC20 token的余额查询和转账交易:

注意:Erc20 token转账时,需在手机钱包中确认弹出的提示信息。

2.5 部署ERC721合约

command> 下输入deploy erc721,然后按回车,将演示ERC721合约的部署:

注意:合约部署也是交易,因此将在手机钱包弹出提示信息,需确认后才可完成合约部署交易。

2.6 ERC721 token的查询和转账

command> 下输入erc721,然后按回车,将演示ERC721 token的余额查询和转账交易:

注意:Erc721 token转账时,需在手机钱包中确认弹出的提示信息。

3、使用WalletConnect

WalletConnect协议可以帮助桌面PC应用利用手机钱包完成区块链的访问,其时序如下图所示:

WalletConnect是入口类,可以利用它完成协议会话的建立,并在此会话基础上,完成余额查询、 转账、部署合约、合约调用等任务。

3.1 WalletConnect的实例化

创建WalletConnect实例需要传入一个描述应用的ClientMeta对象。例如,下面的代码使用指定 的ClientMeta创建一个新的WalletConnect实例:

ClientMeta meta(
  "sample app",                           //名称
  "http://app.mysite.com",                //网址
  {"http://app.mysite.com/icon.ico"},     //图标集
  "my first c++ blockchain app"           //描述信息
);

WalletConnect wc(meta);                   //创建WalletConnect对象

ClientMeta对象包含四个字段:

  • name:应用名称,字符串。
  • url:应用的线上地址,也作为应用的唯一标识符,字符串。
  • icons:应用的图标地址,可多个,字符串数组。
  • description:应用的描述信息,字符串。

当应用通过WalletConnect协议提交交易时,该名称将出现在手机钱包的提示信息中心。

3.2 创建协议会话

使用WalletConnect对象的createSession()方法创建与WalletConnect服务器和手机钱包的 三方会话连接,在此过程中,WalletConnect对象将调用开发者提供的DisplayQrCode事件处理 代码,开发者应当向用户展示可供手机钱包扫描的二维码。

例如,下面的代码在DisplayQrCode事件处理中将传入的二维码对象转换为SVG文件并打开该文件, 以便用户扫码确认连接:

if(!wc.isConnected())                                                //仅当未建立会话时执行    
{
  wc.addEventListener<void(QrCode)>(                                
    "DisplayQrCode",                                                 //监听DisplayQrCode事件
    [](QrCode qrc){                                                  //事件处理程序   
      std::ofstream fout("wc.svg");                                       
      fout << qrc.toSVG();                                           //将二维码转为SVG写入文件
      fout.close();
      ShellExecuteA(NULL, "open", "wc.svg", NULL, NULL, SW_SHOW);    //打开生成的SVG文件
    }
  );
  wc.createSession();                                                //创建三方会话
}

用户使用手机钱包扫码后,将在手机钱包上弹出连接请求信息,用户确认后即完成会话的建立。 使用WalletConnect对象的getAccount()方法可查询当前连接的账号:

if(wc.isConnected())
{
  std::cout << wc.getAccount() << std::endl;
}

3.3 原生token的查询和转账

当会话建立后,可以利用WalletConnect对象查询原生token的余额或提交转账等交易。

例如,下面的代码利用getBalance()方法查询当前所连接账号的余额:

u256 balance = wc.getBalance(wc.getAccount());
std::cout << "balance: " << balance << std::endl;

u256表示256bits(32 bytes)的无符号整数,对应EVM虚拟机中的u256类型。

使用WalletConnect对象的transfer()方法向指定账号进行转账,并返回交易ID。 例如:

std::string txid = wc.transfer(                     //转账
  "0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0",     //目标地址
  u256("1000000000")                                //转账数量
);
std::cout << "txid: " << txid << std::endl;

3.4 ERC20 token的查询、转账

WalletConnect对象的erc20()方法返回一个Erc20对象,可用于ERC20 token的 查询与转账。

例如,下面的代码读取指定ERC20 token的基本信息、查询当前账号的余额,并向其他账号转账:

Erc20 token = wc.erc20(
  "0xcfeb869f69431e42cdb54a4f4f105c19c080a601"      //ERC20 token的地址
);
std::string name = token.name();                    //查询名称
std::string symbol = token.symbol();                //查询符号
int decimals = token.decimals();                    //查询小数位数
u256 balance = token.balanceOf(wc.getAccount());    //查询余额
std::string txid = token.transfer(                  //转账
  "0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0",     //目标地址
  u256("1000000000")                                //转账数量
);

3.5 ERC721 token的查询与转账

WalletConnect对象的erc721()方法返回一个Erc721对象,可用于ERC721 token的 查询与交易。

例如,下面的代码读取指定ERC721 token的基本信息、铸造并转账:

Erc721 token = wc.erc721(
  "0xe982e462b094850f12af94d21d470e21be9d0e9c"            //ERC721 token的地址
);

std::cout << "name" << token.name() << std::endl;         //显示名称
std::cout << "symbol" << token.symbol() << std::endl;     //显示符号

std::string txid = token.min(                             //铸造NFT
  wc.getAccount()                                         //接收账号  
);            
wc.waitForReceipt(txid);                                  //等待交易确认
u256 id = token.totalSupply();                            //读取NFT ID
std::cout << "owner: " << token.ownerOf(id) << std::endl; //显示持有NFT的账号

txid = token.transferFrom(                                //转账  
  wc.getAccount(),                                        //转出账号
  "0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0",           //转入账号
  id                                                      //NFT ID
);
wc.waitForReceipt(txid);                                  //等待交易确认
std::cout << "owner: " << token.ownerOf(id) << std::endl; //显示持有NFT的账号

3.6 查询合约事件

使用Erc20、Erc721等合约对象的getEvents()方法查询指定区块范围内触发的合约事件, 例如查询最近10个区块的事件:

u256 lastblk = wc.blockNumber();                          //读取最新区块高度
auto events = token.getEvents(lastblk - 10, lastblk);     //查询事件
for(int i=0;i<events.size();i++){                         //遍历返回的事件
  std::cout << "event: " << events[i].name << std::endl;  //显示事件名称
  for(int j=0;j<events[i].params.size();j++){             //遍历事件参数
    std::cout << j << ": " 
        << events[i].params[j].toString()                 //显示ABI解码后的参数值
        << std::endl;
  }
}

3.7 部署合约

使用WalletConnect对象的deployContract()方法部署智能合约,需要传入合约编译后生成 的ABI和字节码。

例如,下面的代码部署合约并显示最终的部署地址:

std::string abi = "...";                                  //合约abi
std::string bin = "...";                                  //合约字节码
std::string txid = wc.deployContract(abi, bin);           //部署合约
auto receipt = wc.waitForReceipt(txid);
std::cout << "deployed at: "                                 
    << receipt["contractAddress"].get<std::string>()      //显示部署地址
    << std::endl;

如果合约的构造函数需要参数,可以直接在deployContract()的参数列表中追加。 例如:

std::string txid = wc.deployContract(
  abi, bin,                                               //ABI和字节码
  param1, param2, param3                                  //构造函数参数
)

3.8 WallectConnect事件监听

WallectConnect对象提供了addEventListener()方法用于监听会话过程中的事件:

  • ConnectionOpened

当与服务器成功建立Socket连接时触发。例如:

wc.addEventListener<void()>("ConnectionOpened", [](){
  std::cout << "connection opened" << std::endl;
});
  • ConnectionClosed

当与服务器的Socket连接关闭时触发。例如:

wc.addEventListener<void()>("ConnectionClosed", [](){
  std::cout << "connection closed" << std::endl;
});
  • ConnectionFailed

当与服务器的Socket连接失败时触发。例如:

wc.addEventListener<void()>("ConnectionFailed", [](){
  std::cout << "connection failed" << std::endl;
});
  • SessionApproved

当用户在手机钱包中确认三方会话时触发。例如:

wc.addEventListener<void(int, std::vector<std::string>)>(
  "SessionApproved", [](int chainId, std::vector<std::string>){
    std::cout << "session approved" << std::endl;
    std::cout << "chain id: " << chainId << std::endl;
    std::cout << "accounts[0]: " << accounts[0] << std::endl;
  });
  • SessionRejected

当用户在手机钱包中拒绝三方会话时触发。例如:

wc.addEventListener<void()>("SessionRejected", [](){
  std::cout << "session rejected" << std::endl;
});
  • SessionUpdated

当用户在手机钱包中切换账号或切换接入的区块链时触发。例如:

wc.addEventListener<void(int, std::vector<std::string>)>(
  "SessionUpdated", [](int chainId, std::vector<std::string>){
    std::cout << "session updated" << std::endl;
    std::cout << "chain id: " << chainId << std::endl;
    std::cout << "accounts[0]: " << accounts[0] << std::endl;
  });
  • SessionKilled

当用户在手机钱包中移除之前确认的三方会话时触发。例如:

wc.addEventListener<void()>("SessionKilled", [](){
  std::cout << "session killed" << std::endl;
});
通过 NowPayments 打赏