ContractOperation

Provides contract related operations. For more about writing smart contract, see Aergo Smart Contract.

Deploy

Smart contract를 배포합니다. 보통 배포 절차는 다음과 같습니다.

배포 -> confirm기다림 -> contract tx receipt 받음 -> contract 주소 확인 -> contract interface 조회

Contract definition에 대해 더 자세히 알고 싶으시면 다음의 문서를 참고하세요 ContractDefinition.

AergoKey signer = richKey;

// made by aergoluac --payload {some_contract}.lua
String encodedContract = contractPayload;

// make a contract definition
ContractDefinition contractDefinition = ContractDefinition.newBuilder()
    .encodedContract(encodedContract)
    .build();

// deploy
long nonce = nonceProvider.incrementAndGetNonce(signer.getAddress());
TxHash txHash = client.getContractOperation().deployTx(signer, contractDefinition,
    nonce, Fee.ZERO);
System.out.println("Contract deployment tx hash: " + txHash);

// wait deploy contract to be confirmed
Thread.sleep(2200L);

// get contract tx receipt
ContractTxReceipt contractTxReceipt = client.getContractOperation()
    .getContractTxReceipt(txHash);
System.out.println("Contract tx receipt: " + contractTxReceipt);

// find a contract address
ContractAddress contractAddress = contractTxReceipt.getContractAddress();

// get contract interface
ContractInterface contractInterface = client.getContractOperation()
    .getContractInterface(contractAddress);
System.out.println("Contract interface: " + contractInterface);

Re-Deploy

이미 배포된 contract에 재배포합니다. 재배포 하게 되면 contract의 상태는 바꾸지 않고 logic을 바꿀 수 있습니다. 이 연산은 private mode로 돌고 있는 aergo에서만 동작합니다. Contract definition에 대해 더 자세히 알고 싶으시면 다음의 문서를 참고하세요 ContractDefinition.

// prepare signer
AergoKey signer = richKey;

// made by aergoluac --payload {some_contract}.lua
String encodedContract = contractPayload;

// make a contract definition
ContractDefinition newDefinition = ContractDefinition.newBuilder()
    .encodedContract(encodedContract)
    .build();

// redeploy
ContractAddress contractAddress = contractAddressKeep;
long nonce = nonceProvider.incrementAndGetNonce(signer.getAddress());
TxHash txHash = client.getContractOperation()
    .redeployTx(signer, contractAddress, newDefinition, nonce, Fee.ZERO);
System.out.println("Redeploy tx hash: " + txHash);

Get Contract Tx Receipt

contract tx에 대한 영수증을 조회합니다. 해당되는 정보가 없을 경우 null을 리턴합니다.

TxHash txHash = TxHash.of("EGXNDgjY2vQ6uuP3UF3dNXud54dF4FNVY181kaeQ26H9");
ContractTxReceipt contractTxReceipt = client.getContractOperation()
    .getContractTxReceipt(txHash);
System.out.println("ContractTxReceipt: " + contractTxReceipt);

Get Contract Interface

contract에 대한 interface를 조회합니다. 해당되는 정보가 없을 경우 null을 리턴합니다.

ContractAddress contractAddress = ContractAddress
    .of("AmNrsAqkXhQfE6sGxTutQkf9ekaYowaJFLekEm8qvDr1RB1AnsiM");
ContractInterface contractInterface = client.getContractOperation()
    .getContractInterface(contractAddress);
System.out.println("ContractInterface: " + contractInterface);

Execute

배포되어 있는 contract를 실행합니다. Contract invocation에 대해 더 자세히 알고 싶으시면 다음의 문서를 참고하세요 ContractInvocation.

// prepare signer
AergoKey signer = richKey;

// make a contract invocation
ContractInterface contractInterface = contractInterfaceKeep;
ContractInvocation invocation = contractInterface.newInvocationBuilder()
    .function("set")
    .args("key", 333, "test2")
    .build();

// execute
long nonce = nonceProvider.incrementAndGetNonce(signer.getAddress());
TxHash txHash = client.getContractOperation()
    .executeTx(signer, invocation, nonce, Fee.ZERO);
System.out.println("Execute tx hash: " + txHash);

Query

배포되어 있는 contract의 상태를 조회합니다. Contract invocation에 대해 더 자세히 알고 싶으시면 다음의 문서를 참고하세요 ContractInvocation.

// java bean
public class Data {

  protected int intVal;

  protected String stringVal;

  public int getIntVal() {
    return intVal;
  }

  public void setIntVal(int intVal) {
    this.intVal = intVal;
  }

  public String getStringVal() {
    return stringVal;
  }

  public void setStringVal(String stringVal) {
    this.stringVal = stringVal;
  }

  @Override
  public String toString() {
    return "Data [intVal=" + intVal + ", stringVal=" + stringVal + "]";
  }

}
// make a contract invocation
ContractInterface contractInterface = contractInterfaceKeep;
ContractInvocation query = contractInterface.newInvocationBuilder()
    .function("get")
    .args("key")
    .build();

// query contract
ContractResult queryResult = client.getContractOperation().query(query);
Data data = queryResult.bind(Data.class);
System.out.println("Raw contract result: " + queryResult); // { "intVal": 123, "stringVal": "test" }
System.out.println("Binded data: " + data);

List Event

특정 block에 발생한 event정보를 조회합니다. Event filter에 대해 더 자세히 알고 싶으시면 다음의 문서를 참고하세요 EventFilter.

ContractAddress contractAddress = contractAddressKeep;
EventFilter eventFilter = EventFilter.newBuilder(contractAddress)
    .eventName("set")
    .args("key")
    .recentBlockCount(1000)
    .build();
List<Event> events = client.getContractOperation().listEvents(eventFilter);
System.out.println("Events: " + events);

Event Subscription

새롭게 발행하는 event정보를 구독합니다. Event filter에 대해 더 자세히 알고 싶으시면 다음의 문서를 참고하세요 EventFilter.

// prepare signer
AergoKey signer = richKey;

// subscribe event
ContractAddress contractAddress = contractAddressKeep;
EventFilter eventFilter = EventFilter.newBuilder(contractAddress).build();
Subscription<Event> subscription = client.getContractOperation()
    .subscribeEvent(eventFilter, new StreamObserver<Event>() {
      @Override
      public void onNext(Event value) {
        System.out.println("Next event: " + value);
      }

      @Override
      public void onError(Throwable t) {
      }

      @Override
      public void onCompleted() {
      }
    });

// execute
ContractInterface contractInterface = contractInterfaceKeep;
ContractInvocation run = contractInterface.newInvocationBuilder()
    .function("set")
    .args("key", 333, "test2")
    .build();
long nonce = nonceProvider.incrementAndGetNonce(signer.getAddress());
client.getContractOperation().executeTx(signer, run, nonce, Fee.ZERO);
Thread.sleep(2200L);

// unsubscribe event
subscription.unsubscribe();