5 web3j对solidity里面的struct对象, java中如何传参呢

solidity结构体
contract test { struct Demo { uint64 uid; uint64 amount; } function send(Demo calldata demo) public {} }

java使用web3j构建参数 :
@Data class Demo extends StaticStruct { public Uint64 uid; public Uint64 amount; public Demo(long uid, long amount) { super(new Type[]{new Uint64(uid),new Uint64(amount)}); }
构建参数可以用这种方式吗? 现在发现上链死活失败
Function function = new Function( "send", List.of(new Demo(1,2)), Collections.emptyList());

第二个问题是 java种怎么打印出来传输的参数呢?
像js就直接是json串
{ "uid":1, "amount":2 }

请先 登录 后评论

4 个回答

Wade - Footprint Analytics CTO
  擅长:数据分析,GameFi,NFT
  1. 可以
import org.web3j.abi.datatypes.Uint64;
import org.web3j.abi.datatypes.generated.Uint64;
import org.web3j.abi.datatypes.DynamicStruct;
import org.web3j.protocol.core.methods.response.EthCall;
import java.util.Arrays;

public class Demo extends DynamicStruct {
    public Uint64 uid;
    public Uint64 amount;

    public Demo(Uint64 uid, Uint64 amount) {
        super(uid, amount);
        this.uid = uid;
        this.amount = amount;
    }

    public Demo(long uid, long amount) {
        this(new Uint64(uid), new Uint64(amount));
    }
}

Function function = new Function(
    "send", 
    Arrays.asList(new Demo(new Uint64(1), new Uint64(2))), 
    Collections.emptyList()
);

2.重写toString方法

        @Override
        public String toString() {
            return "{" +
                    "\"uid\":" + uid.getValue() +
                    ", \"amount\":" + amount.getValue() +
                    '}';
        }

请先 登录 后评论
Wade - Footprint Analytics CTO
  擅长:数据分析,GameFi,NFT
pragma solidity ^0.8.0;

contract Test {
    struct Demo {
        uint64 uid;
        uint64 amount;
    }

    function send(Demo calldata demo) public {
        // Function implementation
    }
}

java

import org.web3j.abi.datatypes.StaticStruct;
import org.web3j.abi.datatypes.generated.Uint64;
import lombok.Data;

@Data
public class Demo extends StaticStruct {
    public Uint64 uid;
    public Uint64 amount;

    public Demo(long uid, long amount) {
        super(new Uint64(uid), new Uint64(amount));
        this.uid = new Uint64(uid);
        this.amount = new Uint64(amount);
    }

    @Override
    public String toString() {
        return "{ \"uid\": " + uid.getValue() + ", \"amount\": " + amount.getValue() + " }";
    }
}

调用

import org.web3j.abi.datatypes.Function;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.tx.Contract;
import org.web3j.tx.gas.DefaultGasProvider;

import java.util.Collections;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // Initialize Web3j, credentials, and contract instance
        // Web3j web3j = Web3j.build(new HttpService("http://localhost:8545"));
        // Credentials credentials = WalletUtils.loadCredentials("password", "path/to/walletfile");
        // String contractAddress = "0xYourContractAddress";
        // Test contract = Test.load(contractAddress, web3j, credentials, new DefaultGasProvider());

        // Create a Demo instance
        Demo demo = new Demo(1, 2);
        System.out.println("Demo instance: " + demo);

        // Create a Function instance
        Function function = new Function(
            "send",
            List.of(demo),
            Collections.emptyList()
        );

        // Call the contract function
        // TransactionReceipt receipt = contract.executeTransaction(function);
        // System.out.println("Transaction receipt: " + receipt);
    }
}

请先 登录 后评论
jc0803kevin - 合约开发/区块链开发/项目管理

第二个问题可以看看这个https://blog.csdn.net/jc0803kevin/article/details/143363800

请先 登录 后评论
Ric Li C

在 Java 中使用 Web3j 与 Solidity 合约交互时,传递结构体(struct)参数需要正确地构建结构体,并确保数据类型与 Solidity 中定义的类型匹配。以下是如何在 Java 中传递 Solidity 结构体参数的详细说明,以及如何打印传输的参数。

  1. 构建 Solidity 结构体参数
    在 Solidity 中定义的 struct 可以通过 Java 中的 StaticStruct 类进行传递。根据你的代码示例,构建 Demo 结构体的代码大致正确,但可能需要确保类型匹配。

    首先,确保你的 Demo 类继承自 StaticStruct,并且正确实现了构造函数:

    java

import org.web3j.abi.datatypes.StaticStruct;
    import org.web3j.abi.datatypes.generated.Uint64;

    @Data
    public class Demo extends StaticStruct {
        public Uint64 uid;
        public Uint64 amount;

        public Demo(long uid, long amount) {
            super(new Type[]{new Uint64(uid), new Uint64(amount)});
            this.uid = new Uint64(uid);
            this.amount = new Uint64(amount);
        }
    }
  1. 调用合约方法
    在调用合约方法时,你可以使用 Function 类来构造交易。确保 Demo 类的实例被正确创建并传递给 Function:

    java

    import org.web3j.abi.datatypes.Function;
    
    Function function = new Function(
        "send",
        List.of(new Demo(1, 2)),  // 创建 Demo 实例并作为参数传入
        Collections.emptyList()
    );
    
  2. 上链失败的原因
    如果发现上链失败,可能是以下原因导致的:

    结构体参数未正确序列化:确保传递的参数类型与 Solidity 合约中的类型完全匹配。
    合约地址或网络问题:确认合约地址正确,并且网络连接正常。
    Gas 限制:确保交易提供了足够的 Gas 限制。
    合约逻辑问题:合约内的逻辑可能存在问题,导致交易失败。

  3. 打印参数
    在 Java 中,你可以手动构建 JSON 字符串来打印传输的参数,或者使用库(如 Jackson 或 Gson)将对象序列化为 JSON。

    以下是一个示例,使用 Jackson 库来打印参数:

    java

    import com.fasterxml.jackson.databind.ObjectMapper;
    
    ObjectMapper objectMapper = new ObjectMapper();
    Demo demo = new Demo(1, 2);
    String jsonString = objectMapper.writeValueAsString(demo);
    System.out.println(jsonString);  // 打印 {"uid":1,"amount":2}
    
请先 登录 后评论
  • 4 关注
  • 0 收藏,1782 浏览
  • 约队 提出于 2024-08-30 16:45