Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
fulldecent opened this issue Jul 13, 2019 · 3 comments
Open

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

fulldecent opened this issue Jul 13, 2019 · 3 comments

Comments

@fulldecent
Copy link
Contributor

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 fulldecent changed the title Why is it necessary to use avmRule.call? Why is it necessary to use ABIStreamingEncoder and avmRule.call? Jul 13, 2019
@fulldecent
Copy link
Contributor Author

This fix will probably require changing

static {
}

Into

public static void deploy(ACTUAL PARAMETERS) {
}

@jeff-aion
Copy link
Contributor

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
Copy link
Contributor Author

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...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants