java-sdk icon indicating copy to clipboard operation
java-sdk copied to clipboard

Solidity转java代码不支持struct等复杂数据类型

Open cyjseagull opened this issue 4 years ago • 7 comments

cyjseagull avatar Jan 18 '21 04:01 cyjseagull

same issue in my project

MoneyNotFoundException avatar May 27 '21 06:05 MoneyNotFoundException

same

zhangbincheng1997 avatar Sep 04 '21 21:09 zhangbincheng1997

支持了吗 ?我想要这样的合约内容。 pragma solidity >0.4.24 <0.6.11; pragma experimental ABIEncoderV2; contract Unt{ struct Person { string name; uint age; }

function set(Person memory person) public pure  returns(Person[] memory) {
    Person[] memory ps = new Person[](1);
    ps[0] = person;
    return ps;
}

}

这个可以编译也可以部署。 @zhangbincheng1997 @MoneyNotFoundException

15168326318 avatar Nov 11 '21 08:11 15168326318

提测文档

特性描述

solidity生成java代码支持struct、struct数组、struct嵌套。

代码修改点:

1、在datatypes中增加StructType、DynamicStruct、StaticStruct来表示struct类型 2、TypeEncoder、TypeDecoder增加对DynamicStruct、StaticStruct类型的编解码 3、FunctionReturnDecoder中增加对struct返回值、struct数组返回值的解析支持,可以解析成Java对象 4、AbiTypes中增加对struct这种自定义类型的映射,可以将struct映射成对应的java类 5、ABIDefinition 中增加一些struct的一些标识方法,便于判断和比较struct 6、SolidityContractWrapper 增加了将struct类型转成Java Bean逻辑同生产是生产的合约类的一个内部类,生产的合约类支持参数、返回值都有struct类型,并可以为struct类型生产函数模板代码。 7、Contract 小改动,返回值类型转换增加更多判断来支持struct类型转换。

影响的功能范围

1、影响solidity合约生产Java代码的完整逻辑 2、影响生产的合约java代码发送读和写交易的发送和返回值解析 3、影响console的合约调用

测试项

1、完整回归测试solidity合约生产Java合约,以及Java合约的调用 2、新增加合约中包含struct测试用例 2.1 合约方法参数/返回值有struct 2.2 合约方法参数/返回值有struct数组 2.3 合约方法参数/返回值有struct中嵌套struct 2.4 合约方法参数/返回值有struct中嵌套struct数组 3、console回归测试合约调用

测试合约用例样品:

1、合约方法参数/返回值有struct: StructTest1.sol

pragma solidity >0.4.24 <0.6.11;
pragma experimental ABIEncoderV2;

contract StructTest1 {

    struct Person {
        string name;
        uint age;
    }
    
    Person data;

    function get(Person memory person) public pure returns(Person memory) {
        
        Person memory out = Person(person.name, person.age);
        return out;
    }
    
    function set(Person memory person) public returns(Person memory) {
        
        data = Person(person.name, person.age + 1);
        return data;
    }
}

2、合约方法参数/返回值有struct数组: StructTest2.sol

pragma solidity >0.4.24 <0.6.11;
pragma experimental ABIEncoderV2;

contract StructTest2 {

    struct Person {
        string name;
        uint age;
    }
    
    Person[] data;

    function get(Person[] memory person) public pure returns(Person[] memory) {
        
        Person[] memory ps = new Person[](person.length);
        for (uint i = 0; i < person.length; i++) {
            ps[i] = person[i];
        }
        
        return ps;
    }
    
    function set(Person[] memory person) public returns(Person[] ) {
        
        for (uint i = 0; i < person.length; i++) {
            data.push(Person(person[i].name, person[i].age+1));
        }
        
        return data;
    }
}

3、合约方法参数/返回值有struct中嵌套struct: StructTest3.sol

pragma solidity >0.4.24 <0.6.11;
pragma experimental ABIEncoderV2;

contract StructTest3 {

    struct Person {
        string name;
        uint age;
        Account account;
    }

    struct Account {
        address accountAddr;
        int points;
    }
    
    Person[] data;

    function get(Person[] memory person) public pure returns(Person[] memory) {
        
        Person[] memory ps = new Person[](person.length);
        for (uint i = 0; i < person.length; i++) {
            ps[i] = person[i];
        }
        
        return ps;
    }
    
    function register(Person memory person) public returns(Person[] ) {
        Account memory account = Account(msg.sender, 100);
        Person memory tmp = Person(person.name, person.age+1, account);
        data.push(tmp);
    
        return data;
    }
}

这是可以参考使用测试调用StructTest合约的java代码,

package org.fisco.bcos.sdk.codegen;

import org.apache.commons.io.FileUtils;
import org.fisco.bcos.sdk.BcosSDK;
import org.fisco.bcos.sdk.abi.datatypes.Address;
import org.fisco.bcos.sdk.abi.datatypes.DynamicArray;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple1;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.client.protocol.response.BlockNumber;
import org.fisco.bcos.sdk.codegen.exceptions.CodeGenException;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.transaction.model.exception.ContractException;

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

public class SolidityContractGeneratorTest {
    static Path solDir = Paths.get("D:/test/codegen/contracts/solidity");
    static Path abiDir = Paths.get("D:/test/codegen/contracts/sdk/abi");
    static Path binDir = Paths.get("D:/test/codegen/contracts/sdk/bin");
    static Path smBinDir = Paths.get("D:/test/codegen/contracts/sdk/bin/sm");

    public static void testStruct2() throws ContractException {

        BcosSDK sdk =  BcosSDK.build("D:/test/codegen/config.toml");
        Client client = sdk.getClient(Integer.valueOf(1));

        CryptoKeyPair cryptoKeyPair = client.getCryptoSuite().getCryptoKeyPair();
        StructTest2 structTest2 = StructTest2.deploy(client, cryptoKeyPair);
//        StructTest2 structTest2 = StructTest2.load("0x0e92dfbb75496954a94e769459ae82ace05671e9", client, cryptoKeyPair);
        System.out.println("address: " + structTest2.getContractAddress());

        StructTest2.Struct0 person = new StructTest2.Struct0("dw", BigInteger.valueOf(12));

        List<StructTest2.Struct0> list = Arrays.asList(new StructTest2.Struct0("dw", BigInteger.valueOf(12)), new StructTest2.Struct0("cc", BigInteger.valueOf(13)));
        DynamicArray<StructTest2.Struct0> struct0DynamicArray = new DynamicArray<>(list);
//        DynamicArray<StructTest2.Struct0> getOutput = structTest2.get(struct0DynamicArray);
        TransactionReceipt receipt = structTest2.set(struct0DynamicArray);
        Tuple1<DynamicArray<StructTest2.Struct0>> setOutput = structTest2.getSetOutput(receipt);
        Tuple1<DynamicArray<StructTest2.Struct0>> setInput = structTest2.getSetInput(receipt);

//        System.out.println(getOutput);
        System.out.println(setOutput);
        System.out.println(setInput);
    }

    public static void testStruct3() throws ContractException {

        BcosSDK sdk =  BcosSDK.build("D:/test/codegen/config.toml");
        Client client = sdk.getClient(Integer.valueOf(1));

        CryptoKeyPair cryptoKeyPair = client.getCryptoSuite().getCryptoKeyPair();
//        StructTest3 structTest3 = StructTest3.deploy(client, cryptoKeyPair);
        StructTest3 structTest3 = StructTest3.load("0xd3212f615961c4f0ae0cb82427e0856362299bec", client, cryptoKeyPair);
        System.out.println("address: " + structTest3.getContractAddress());

        StructTest3.Struct0 account1 = new StructTest3.Struct0(cryptoKeyPair.getAddress(), BigInteger.valueOf(30));
        StructTest3.Struct1 person1 = new StructTest3.Struct1("dw", BigInteger.valueOf(12), account1);
        StructTest3.Struct0 account2 = new StructTest3.Struct0(cryptoKeyPair.getAddress(), BigInteger.valueOf(40));
        StructTest3.Struct1 person2 = new StructTest3.Struct1("cc", BigInteger.valueOf(13), account2);


        List<StructTest3.Struct1> list = Arrays.asList(person1, person2);
        DynamicArray<StructTest3.Struct1> struct0DynamicArray = new DynamicArray(list);
//        DynamicArray<StructTest3.Struct1> getOutput = structTest3.get(struct0DynamicArray);
        TransactionReceipt receipt = structTest3.register(person1);

        Tuple1<DynamicArray<StructTest3.Struct1>> registerOutput = structTest3.getRegisterOutput(receipt);
        Tuple1<StructTest3.Struct1> registerInput = structTest3.getRegisterInput(receipt);

//        System.out.println(getOutput);
        System.out.println(registerOutput);
        System.out.println(registerInput);
    }

    public static void testStruct1() throws ContractException {

        BcosSDK sdk =  BcosSDK.build("D:/test/codegen/config.toml");
        Client client = sdk.getClient(Integer.valueOf(1));

        CryptoKeyPair cryptoKeyPair = client.getCryptoSuite().getCryptoKeyPair();
        StructTest1 structTest1 = StructTest1.deploy(client, cryptoKeyPair);
//        StructTest structTest = StructTest.load("0x94901efe731e4a5ac9fa68bdeb3fb5aeff4fc934", client, cryptoKeyPair);
        System.out.println("address: " + structTest1.getContractAddress());
        StructTest1.Struct0 person = new StructTest1.Struct0("dw", BigInteger.valueOf(12));
        TransactionReceipt receipt = structTest1.set(person);
        Tuple1<StructTest1.Struct0> setOutput = structTest1.getSetOutput(receipt);
        Tuple1<StructTest1.Struct0> setInput = structTest1.getSetInput(receipt);

//        System.out.println(list);
        System.out.println(setOutput);
        System.out.println(setInput);
    }

    public static void main(String[] args) {
        try {
//            testStruct2();
            testStruct1();
//            testStruct3();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

HelloAldis avatar Apr 11 '22 08:04 HelloAldis

thanks!

------------------ 原始邮件 ------------------ 发件人: @.>; 发送时间: 2022年4月11日(星期一) 下午4:58 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [FISCO-BCOS/java-sdk] Solidity转java代码不支持struct等复杂数据类型 (#248)

特性描述

solidity生成java代码支持struct、struct数组、struct嵌套。

代码修改点:

1、在datatypes中增加StructType、DynamicStruct、StaticStruct来表示struct类型 2、TypeEncoder、TypeDecoder增加对DynamicStruct、StaticStruct类型的编解码 3、FunctionReturnDecoder中增加对struct返回值、struct数组返回值的解析支持,可以解析成Java对象 4、AbiTypes中增加对struct这种自定义类型的映射,可以将struct映射成对应的java类 5、ABIDefinition 中增加一些struct的一些标识方法,便于判断和比较struct 6、SolidityContractWrapper 增加了将struct类型转成Java Bean逻辑同生产是生产的合约类的一个内部类,生产的合约类支持参数、返回值都有struct类型,并可以为struct类型生产函数模板代码。 7、Contract 小改动,返回值类型转换增加更多判断来支持struct类型转换。

影响的功能范围

1、影响solidity合约生产Java代码的完整逻辑 2、影响生产的合约java代码发送读和写交易的发送和返回值解析 3、影响console的合约调用

测试项

1、完整回归测试solidity合约生产Java合约,以及Java合约的调用 2、新增加合约中包含struct测试用例 2.1 合约方法参数/返回值有struct 2.2 合约方法参数/返回值有struct数组 2.3 合约方法参数/返回值有struct中嵌套struct 2.4 合约方法参数/返回值有struct中嵌套struct数组 3、console回归测试合约调用

测试合约用例样品:

1、合约方法参数/返回值有struct: StructTest1.sol pragma solidity >0.4.24 <0.6.11; pragma experimental ABIEncoderV2; contract StructTest1 { struct Person { string name; uint age; } Person data; function get(Person memory person) public pure returns(Person memory) { Person memory out = Person(person.name, person.age); return out; } function set(Person memory person) public returns(Person memory) { data = Person(person.name, person.age + 1); return data; } }

2、合约方法参数/返回值有struct数组: StructTest2.sol pragma solidity >0.4.24 <0.6.11; pragma experimental ABIEncoderV2; contract StructTest2 { struct Person { string name; uint age; } Person[] data; function get(Person[] memory person) public pure returns(Person[] memory) { Person[] memory ps = new Person; for (uint i = 0; i < person.length; i++) { ps[i] = person[i]; } return ps; } function set(Person[] memory person) public returns(Person[] ) { for (uint i = 0; i < person.length; i++) { data.push(Person(person[i].name, person[i].age+1)); } return data; } }

3、合约方法参数/返回值有struct中嵌套struct: StructTest3.sol pragma solidity >0.4.24 <0.6.11; pragma experimental ABIEncoderV2; contract StructTest3 { struct Person { string name; uint age; Account account; } struct Account { address accountAddr; int points; } Person[] data; function get(Person[] memory person) public pure returns(Person[] memory) { Person[] memory ps = new Person; for (uint i = 0; i < person.length; i++) { ps[i] = person[i]; } return ps; } function register(Person memory person) public returns(Person[] ) { Account memory account = Account(msg.sender, 100); Person memory tmp = Person(person.name, person.age+1, account); data.push(tmp); return data; } }

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

15168326318 avatar Apr 11 '22 09:04 15168326318

这个功能哪个版本可以开始支持了呢

shellow avatar Mar 15 '23 01:03 shellow

@ywy2090 @HelloAldis 我使用java-sdk-demo main-2.0 进行测试,发现如下现象

按照此文档顺序执行

image

java-sdk: 2.9.2; solcJVersion 只能选择0.4.25.

image

生成成功,但结构体名称消失, 变为struct0, struct1等等. image

java-sdk: 2.9.2; solcJVersion 选择0.6版本,控制台报错

image image

执行环境

  • mac os

  • java java version "1.8.0_202" Java(TM) SE Runtime Environment (build 1.8.0_202-b08) Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)

  • solidity 版本 image

  • gradle 6.3

请教问题

  1. 请问现在可以支持0.6版本的solc了吗?
  2. 结构体命名可以支持 原名命名 了吗? (而不是替换成Struct0)

windwindwa avatar May 02 '23 14:05 windwindwa