DEV Community

晓道
晓道

Posted on

再谈无ABI函数调用

发了在没有abi文件的情况下调用智能合约方法,web3py实现 | 登链社区 | 深入浅出区块链技术 (learnblockchain.cn)之后,联系我的朋友不少,看来对这块有需求的朋友不少,在和他们交流的过程中,我发现不少人对这块还有一些误区。

一些问题

1、调用合约函数,需要合约完整的abi吗?

不需要,只需要调用函数的函数定义

2、调用别人的合约需要什么?

合约地址,合约函数定义,合约签名,
如果函数能识别,可以直接复制函数定义,定义空函数。

3、会不会因为语言不一样?

不会,本质上都是通过网络连接进行rpc调用,所以需要的东西是一样的。
通过地址调用合约函数,只需要函数签名和参数。

4、目前实现签名替换有语言有哪些?

目前python的已经实现,参考我前面的文章在没有abi文件的情况下调用智能合约方法,web3py实现 | 登链社区 | 深入浅出区块链技术 (learnblockchain.cn)
node ether.js已经实现,放在登链集市ether.js 无abi调用合约函数,关键代码 - 作品详情 - 登链社区 (learnblockchain.cn)

请能用到觉得有点用的朋友支持,如需要其他语言定制版的请联系我。
技术讨论,可以直接评论。

一个演示

部署Greeter2合约,用Greeter的abi进行调用,测试代码中有注释。

合约

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

contract Greeter {
    string private greeting;

    constructor(string memory _greeting) {
        greeting = _greeting;
    }

    function greet() public view returns (string memory) {
        return greeting;
    }

    function greet2(uint256 num) public view returns (string memory) {
        return "greet2";
    }

    function greet3(uint256 num) public view returns (string memory) {
        return "greet3";
    }

    function setGreeting(string memory _greeting) public {
        greeting = _greeting;
    }
}
Enter fullscreen mode Exit fullscreen mode
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

//import "hardhat/console.sol";

contract Greeter2 {
    //string private greeting;

    constructor() {}

    function greet3(uint256 num) public view returns (string memory) {
        return "kjljlkjljlkjlkjgreet3";
    }
}
Enter fullscreen mode Exit fullscreen mode

测试代码

it("Should return the new greeting once it's changed", async function () {
        const Greeter2 = await ethers.getContractFactory("Greeter2");
        const greeter2 = await Greeter2.deploy();
        await greeter2.deployed();
        console.log("sportFactory:", greeter2.address)
        const greeter = await ethers.getContractAt("Greeter", greeter2.address) //使用Greeter的abi greeter2的地址
        const gg = await greeter.greet2(123, "0x02d355dc"); //调用greeter2 的greet3函数,函数签名模式
        console.log("greet2 greet2 sign:", gg.toString())
        const gg2 = await greeter.greet3(123);          //直接调用greeter2 的greet3函数
        console.log("greet2 greet3:", gg2.toString())
    })
Enter fullscreen mode Exit fullscreen mode

输出

sportFactory: 0xF1b66c6FB483574744D5C418c1c8464F1EEd81fa
greet2 greet2 sign: kjljlkjljlkjlkjgreet3
greet2 greet3: kjljlkjljlkjlkjgreet3
Enter fullscreen mode Exit fullscreen mode

Top comments (0)