V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Joker123456789
V2EX  ›  以太坊

有了这个工具包,用 Java 调用智能合约更加简便了

  •  
  •   Joker123456789 · 2022-11-27 20:34:11 +08:00 · 1355 次点击
    这是一个创建于 487 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Magician-ContractsTools 是一个用于调用智能合约的工具包,你可以非常容易地在 Java 程序中调用智能合约进行查询和写入操作。

    有三个内置的标准合约模板,分别是 ERC20 、ERC721 和 ERC1155 ,如果你需要调用这三个合约中的标准函数,可以帮助你非常快速地完成工作。除了内置的合同模板外,如果你需要调用自定义的合同函数也是很容易的,以后我们还会继续增加标准模板。

    此外,还有 InputData 解码和 ETH 查询和转移的工具

    计划支持三种链,ETH ( BSC 、POLYGON 等)、SOL 和 TRON

    导入依赖

    <dependency>
        <groupId>com.github.yuyenews</groupId>
        <artifactId>Magician-ContractsTools</artifactId>
        <version>1.0.0</version>
    </dependency>
    
    <!-- This is the logging package, you must have it or the console will not see anything, any logging package that can bridge with slf4j is supported -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-jdk14</artifactId>
        <version>1.7.12</version>
    </dependency>
    

    合约查询 以及 写入

    String privateKey = ""; // 私钥
    Web3j web3j = Web3j.build(new HttpService("https://data-seed-prebsc-1-s1.binance.org:8545/")); // 链的 RPC 地址
    String contractAddress = "";
    
    EthContractUtil ethContractUtil = EthContractUtil.builder(web3j);
    
    // 查询
    List<Type> result = ethContractUtil.select(
                contractAddress, // 合约地址
                EthAbiCodecTool.getInputData(
                        "balanceOf", // 要调用的方法名称
                        new Address(toAddress) // 方法的参数,如果有多个,可以继续传入下一个参数
                ),  // 要调用的方法的 inputData
                new TypeReference<Uint256>() {} // 方法的返回类型,如果有多个返回值,可以继续传入下一个参数
            );
    
    // 往合约里写入数据
    // gasPrice ,gasLimit 两个参数,如果想用默认值可以不传,或者传 null
    // 如果不传的话,两个参数都必须不传,要传就一起传, 如果设置为 null 的话,可以一个为 null ,一个有值
    SendResultModel sendResultModel = ethContractUtil.sendRawTransaction(
                        senderAddress, // 调用者的地址
                        contractAddress, // 合约地址
                        privateKey, // senderAddress 的私钥
                        new BigInteger("1200000"), // gasPrice ,如果想用默认值 可以直接传 null ,或者不传这个参数
                        new BigInteger("800000"), // gasLimit ,如果想用默认值 可以直接传 null ,或者不传这个参数
                        EthAbiCodecTool.getInputData(
                                "transfer", // 要调用的方法名称
                                new Address(toAddress), // 方法的参数,如果有多个,可以继续传入下一个参数
                                new Uint256(new BigInteger("1000000000000000000")) // 方法的参数,如果有多个,可以继续传入下一个参数
                        ) // 要调用的方法的 inputData
                );
    
    sendResultModel.getEthSendTransaction(); // 发送交易后的结果
    sendResultModel.getEthGetTransactionReceipt(); // 交易成功上链后的结果
    

    合约模板

    目前只有三种模板,后面会继续增加,为了节约篇幅 这里只展示 ERC20 ,详情可以访问官网了解

    调用 ERC20 合约

    查询

    // 调用合约的 totalSupply 函数
    BigInteger total = erc20Contract.totalSupply();
    
    // 调用合约的 balanceOf 函数
    BigInteger amount = erc20Contract.balanceOf("0xb4e32492E9725c3215F1662Cf28Db1862ed1EE84");
    
    // 调用合约的 allowance 函数
    BigInteger amount = erc20Contract.allowance("0xb4e32492E9725c3215F1662Cf28Db1862ed1EE84", "0x552115849813d334C58f2757037F68E2963C4c5e");
    

    写入

    // 调用合约的 transfer 函数
    SendResultModel sendResultModel = erc20Contract.transfer(
                    "0x552115849813d334C58f2757037F68E2963C4c5e", // 转账接收人
                    new BigInteger("1000000000000000000"), // 转账金额
                    "0xb4e32492E9725c3215F1662Cf28Db1862ed1EE84", // 调用者的地址
                    "", // 调用者的私钥
                    null, // gasPrice ,如果传 null ,自动使用默认值
                    null // gasLimit ,如果传 null ,自动使用默认值
            );
    sendResultModel.getEthSendTransaction(); // 发送交易后的结果
    sendResultModel.getEthGetTransactionReceipt(); // 交易成功上链后的结果
    
    // 调用合约的 transferFrom 函数
    SendResultModel sendResultModel = erc20Contract.transferFrom(
                    "0xb4e32492E9725c3215F1662Cf28Db1862ed1EE84", // 转账付款人
                    "0x552115849813d334C58f2757037F68E2963C4c5e", // 转账接收人
                    new BigInteger("1000000000000000000"), // 转账金额
                    "0xb4e32492E9725c3215F1662Cf28Db1862ed1EE84", // 调用者的地址
                    "", // 调用者的私钥
                    null, // gasPrice ,如果传 null ,自动使用默认值
                    null // gasLimit ,如果传 null ,自动使用默认值
            );
    sendResultModel.getEthSendTransaction(); // 发送交易后的结果
    sendResultModel.getEthGetTransactionReceipt(); // 交易成功上链后的结果
    
    // 调用合约的 approve 函数
    SendResultModel sendResultModel = erc20Contract.approve(
                    "0x552115849813d334C58f2757037F68E2963C4c5e", // 被授权人
                    new BigInteger("1000000000000000000"), // 授权金额
                    "0xb4e32492E9725c3215F1662Cf28Db1862ed1EE84", // 调用者的地址
                    "", // 调用者的私钥
                    null, // gasPrice ,如果传 null ,自动使用默认值
                    null // gasLimit ,如果传 null ,自动使用默认值
            );
    sendResultModel.getEthSendTransaction(); // 发送交易后的结果
    sendResultModel.getEthGetTransactionReceipt(); // 交易成功上链后的结果
    

    InputData 编解码

    // 编码
    String inputData = EthAbiCodecTool.getInputData(
                "transfer", // 方法名
                new Address(toAddress), // 参数 1
                new Uint256(new BigInteger("1000000000000000000")) // 参数 2 ,如果还有其他参数,可以继续传入下一个
        );
    
    // 解码
    List<Type> result = EthAbiCodecTool.decoderInputData(
                "0x" + inputData.substring(10), // 去除方法签名的 inputData
                new TypeReference<Address>() {}, // 被编码的方法的参数 1 类型
                new TypeReference<Uint256>() {} // 被编码的方法的参数 2 类型, 如果还有其他参数,可以继续传入下一个
        );
    
    for(Type type : result){
        System.out.println(type.getValue());
    }
    
    // 获取方法签名,其实就是 inputData 的前十位
    String functionCode = EthAbiCodecTool.getFunAbiCode(
                "transfer", // 方法名
                new Address(toAddress), // 参数 1 ,值随意传,反正我们要的方法签名,不是完整的 inputData
                new Uint256(new BigInteger("1000000000000000000")) // 参数 2 ,值随意传,反正我们要的方法签名,不是完整的 inputData ,如果还有其他参数,可以继续传入下一个
        );
    

    主链币查询以及转账

    String privateKey = ""; // 私钥
    Web3j web3j = Web3j.build(new HttpService("https://data-seed-prebsc-1-s1.binance.org:8545/")); // 链的 RPC 地址
    
    // 这种方式是单例的
    EthHelper ethHelper =  MagicianWeb3.getEthBuilder().getEth(web3j);
    // 如果你想创建多个 EthHelper 对象,可以用这种方式
    EthHelper ethHelper = EthHelper.builder(web3j);
    
    // 余额查询
    BigInteger balance = ethHelper.balanceOf(fromAddress);
    
    // 转账
    TransactionReceipt transactionReceipt = ethHelper.transfer(
                toAddress,
                privateKey, 
                BigDecimal.valueOf(1),
                Convert.Unit.ETHER
    );
    

    官网地址

    https://magician-io.com

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2762 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 12:11 · PVG 20:11 · LAX 05:11 · JFK 08:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.