使用starknet.js调用cairo合约时关于Uint256传参问题(starknet.js4.18.0)

StarkNet 是一种无需许可的去中心化 Validity-Rollup(也称为“ZK-Rollup”)零知识证明系统。它作为以太坊上的 L2 网络运行,使任何 dApp 都能实现无限的计算规模——而不会损害以太坊的可组合性和安全性,这要归功于 StarkNet 对最安全和最具可扩展性的加密证明系统——STARK 的依赖。

Cairo是一种用于编写可证明程序的编程语言,其中一方可以向另一方证明某个计算已正确执行。Cairo和类似的证明系统可用于为区块链提供可扩展性。

starknet.js是starknet上类似于ether.js的开发库,由于目前starknet处于早期,而且starknet.js文档也跟不上库更新的速度,因此在使用最新库的时候就会出现一定的问题。比如,当cairo函数参数为Uint256时,按照官方文档的方式传参会出现参数数量的问题。

使用下面这种参数传递方式是没有问题的,但是starknet有一个特色就是可以在一笔交易中同时与多个合约进行交互(multiCall),采用这样的方式无法使用starknet的这个功能在这里插入图片描述
使用这种方式传参是会出现问题的在这里插入图片描述
发送交易之后可以看到出现下面的情况。这是因为采用这样的方式传参,会把参数数组的长度一并打包提交,实际提交的数据是 [ 1 , 100 ] [1,100] [1,100],在cairo语言中,Uint256是有由两个felt构成的,结构为[felt, felt],第一个元素为低位,第二个元素为高位,所以实际提交的数据会很大。
在这里插入图片描述
解决办法有两种,各有优缺点。

  • 第一种是直接用数组传递参数,比如说在Erc20 token的授权函数中,使用如下的方式传递参数
signer.execute({
    
    
            contractAddress: contractAddress,
            entrypoint: "approve", 
            calldata: [spenderAddress, spendValue, '0'] 
          });

采用这种方式传递参数是直接将Uint256拆分为低位和高位两个元素进行传递,简单直观,坏处是不容易看出具体传递的实参对应哪个形参。

  • 第二种方式是使用compileCalldata,将Uint256当做结构体来处理,代码如下
signer.execute(
          {
    
    
            contractAddress: contractAddress,
            entrypoint: "approve", 
            calldata: stark.compileCalldata({
    
    
                spender: spenderAddress,
                amount: {
    
    type: 'struct', low: spendValue, high: '0'},
              })
          }
        );

采用这种方式的好处就是能够清晰的看到参数对应关系,坏处是增加了代码量。

当然,由于现在starknet.js也处于开发的早期,相信经过一段时间的发展,starknet.js会像ethers.js一样好用。

猜你喜欢

转载自blog.csdn.net/kongtaoxing/article/details/128593355