-
Notifications
You must be signed in to change notification settings - Fork 2
Smart Contract Interface
Etherspace turns a Smart Contract into a Java/Kotlin interface by using annotations.
All the methods in the interface need to be annotated either by @cc.etherspace.Call
or @cc.etherspace.Send
.
The method name is the function name of the underlying Smart Contract function. (or you can override it with @Call.funcationName
)
public interface Greeter {
@Send(functionName = "newGreeting")
TransactionReceipt anotherNewGreeting(String greeting) throws IOException;
}
Method annotated with @Call
represent it's a constant(or View, Pure) function.
The type and order of input/output parameters must match those defined in the Smart Contract function.
Corresponding Solidity/Java Types are defined in Solidity Data Types.
public interface Greeter {
@Call
String greet() throws IOException;
}
Method annotated with @Send
represent it's a function with transaction.
The type and order of input parameters must match those defined in the Smart Contract function.
The output parameter can be either TransactionReceipt
or String
(Transaction Hash).
-
cc.etherspace.TransactionReceipt
Returns the transaction receipt of this transaction. This method will wait for the block completed.
-
String
(Transaction Hash)Returns the transaction hash without waiting for the block completed. This method will return right after the node accepted the transaction. (but not yet completed)
// Java
public interface Greeter {
@Send
String newGreeting(String greeting) throws IOException;
@Send(functionName = "newGreeting")
TransactionReceipt newGreetingWithReceipt(String greeting) throws IOException;
}
Adding a @cc.etherspace.Gas
annotation to SmartContract interface or method to override the default gas settings.
@Gas(gas = "8000000", gasPrice = "22000000000")
public interface Greeter {
@Send
@Gas(gas = "8000000", gasPrice = "22000000000")
TransactionReceipt newGreeting(String greeting) throws IOException;
}
An Options
can be appended to the parameter list in Smart Contract methods.
Properties in Options
will override predefined settings in runtime. (Gas, Credentials, ...)
public interface Greeter {
@Call
String greet() throws IOException;
}
EtherSpace etherSpace = new EtherSpace.Builder()
.provider("https://rinkeby.infura.io/") // Or your local node
.build();
Greeter greeter = etherSpace.create(SMART_CONTRACT_ADDRESS, Greeter.class);
Options options = new Options(BigInteger.ZERO, BigInteger.valueOf(8_000_000), BigInteger.valueOf(22_000_000_000L), new Credentials(YOUR_PRIVATE_KEY_OR_WALLET));
TransactionReceipt receipt = greeter.newGreeting("Hello World", options);
For types in Solidity, below is a list of their corresponding Java Types:
Solidity Type | Java Type |
---|---|
string | java.lang.String |
bool | java.lang.Boolean |
int16 | java.lang.Short |
int32 | java.lang.Integer |
int64 | java.lang.Long |
int / int256 | java.math.BigInteger |
uint16 | unsigned.Ushort |
uint32 | unsigned.Uint |
uint64 | unsigned.Ulong |
uint / uint256 | cc.etherspace.SolUint256 |
int8 ~ int248 (excluding int16,int32,int64) |
cc.etherspace.SolInt8 ~ cc.etherspace.SolInt248
|
uint8 ~ uint248 (excluding uint16,uint32,uint64) |
cc.etherspace.SolUint8 ~ cc.etherspace.SolUint248
|
address | cc.etherspace.SolAddress |
byte / byte1 | java.lang.Byte |
byte2 ~ byte32 |
cc.etherspace.SolBytes2 ~ cc.etherspace.SolBytes32
|
bytes | byte[] |
dynamic array |
java.util.List<T> (T must be one of the Java Types listed above.) |
fixed size array |
cc.etherspace.SolArray1<T> ~ cc.etherspace.SolArray32<T> (T must be one of the Java Types listed above.) |
Functions with multiple return values should use Pair
, Triple
, Tuples
as the values container.
Number of Returns | Java Type |
---|---|
2 | kotlin.Pair |
3 | kotlin.Triple |
4 | cc.etherspace.Tuple4 |
5 | cc.etherspace.Tuple5 |
6 | cc.etherspace.Tuple6 |
7 | cc.etherspace.Tuple7 |
8 | cc.etherspace.Tuple8 |
9 | cc.etherspace.Tuple9 |
10 | cc.etherspace.Tuple10 |
For example, a Smart Contract function with two return values:
// Kotlin
interface Greeter {
@Throws(IOException::class)
@Call
fun greet(): Pair<String, String>
}
// Java
public interface Greeter {
@Call
Pair<String, String> greet() throws IOException;
}
Events defined in Smart Contract need be declared as classes in Java/Kotlin.
For example, we have an Modified
event defined in Smart Contract:
event Modified(
string indexed oldGreetingIdx, string indexed newGreetingIdx,
string oldGreeting, string newGreeting);
The corresponding Modified
event is defined in Kotlin/Java below.
// Kotlin
data class Modified @EventConstructor constructor(
@Indexed(String::class) val oldGreetingIdx: SolBytes32,
@Indexed(String::class) val newGreetingIdx: SolBytes32,
val oldGreeting: String,
val newGreeting: String)
// Java
class Modified {
private SolBytes32 oldGreetingIdx;
private SolBytes32 newGreetingIdx;
private String oldGreeting;
private String newGreeting;
@EventConstructor
public Modified(@Indexed(String.class) SolBytes32 oldGreetingIdx, @Indexed(String.class) SolBytes32 newGreetingIdx, String oldGreeting, String newGreeting) {
this.oldGreetingIdx = oldGreetingIdx;
this.newGreetingIdx = newGreetingIdx;
this.oldGreeting = oldGreeting;
this.newGreeting = newGreeting;
}
// getters/setters ... etc
}
One of the public constructors of the event class needs to be annotated with @cc.etherspace.EventConstructor
and contains the same type and order of parameters.
All the indexed parameters need to be annotated with @cc.etherspace.Indexed
with the Type
defined in Smart Contract.
For all array types (string and array) in Solidity, the parameters will be @cc.etherspace.SolBytes32
instead. (See Events in Solidity document)
After TransactionReceipt
received, you can list the received events from transaction logs:
// Kotlin
val receipt = greeter.newGreeting("Hello World")
val events = receipt.listEvents(Modified::class.java)
// Java
TransactionReceipt receipt = greeter.newGreeting("Hello World");
List<Event<Modified>> events = receipt.listEvents(Modified.class);