aionnetwork / AVM

Enabling Java code to run in a blockchain environment
https://theoan.com/
MIT License
49 stars 25 forks source link

Why is it necessary to use ABIStreamingEncoder and avmRule.call? #401

Open fulldecent opened 5 years ago

fulldecent commented 5 years ago

Using ABIStreamingEncoder with avmRule.call is a low-level technique that 99% of contract developers should not need to know about. This is bad:

public void deployDapp() {
    ABIStreamingEncoder encoder = new ABIStreamingEncoder();
    byte[] data = encoder.encodeOneString(tokenName)
                            .encodeOneString(tokenSymbol)
                            .encodeOneString(tokenUriBase)
                            .toBytes();
    byte[] contractData = avmRule.getDappBytes(ATSTokenContract.class, data, ATSTokenContractEvents.class, ATSTokenContractKeyValueStorage.class);
    contractAddress = avmRule.deploy(deployer, BigInteger.ZERO, contractData).getDappAddress();
}

Instead, during the compilation process please generate a new artifact.

Currently this ABI artifact is generated. Example:

0.0
org.aion.SomeContract
Clinit: ()
public static Address someFunction(byte[])

But actually you can also generate this artifact:

package org.aion;

import avm.Address;
import org.aion.avm.userlib.abi.ABIStreamingEncoder;
import java.math.BigInteger;

public class EncoderForSomeContract {
    bytes[] public someFunction(BigInteger actualParameterName) {
        return new ABIStreamingEncoder()
                .encoder.encodeOneString(tokenName)
                .encodeOneByteArray(actualParameterName)
                .toBytes();
    }
}

End result is the above can be refactored into this new type safe equivalent:

public void deployDapp() {
    byte[] data = EncoderForSomeContract.deploy(tokenName, tokenSymbol, tokenUriBase);
    byte[] contractData = avmRule.getDappBytes(ATSTokenContract.class, data, ATSTokenContractEvents.class, ATSTokenContractKeyValueStorage.class);
    contractAddress = avmRule.deploy(deployer, BigInteger.ZERO, contractData).getDappAddress();
}

The contract publisher would distribute this encoder file as a courtesy to other developers that want to interact with their deployed contract using Java.

fulldecent commented 5 years ago

This fix will probably require changing

static {
}

Into

public static void deploy(ACTUAL PARAMETERS) {
}
jeff-aion commented 5 years ago

Consuming the ABI in order to generate type-safe serializers is something I believe is currently being done as part of some larger down-stream tooling. I am going to leave this item open to remind us to verify that this is included as part of that work (and can be generally used - not just part of a specific project) since I do agree that it is helpful and not difficult to build.

fulldecent commented 5 years ago

This is implemented here

https://github.com/fulldecent/aion-aip010/blob/master/src/main/java/org/aion/AIP010.java#L45-L70

Cool, I feel like I'm touching on the right points here...