Установка и использование платформы
Создание смарт-контрактов с помощью Java/Kotlin Contract SDK¶
В этом разделе описан Java/Kotlin Сontract SDK Toolkit – инструментарий для разработки, тестирования и развертывания Docker смарт-контрактов в публичных блокчейн сетях Waves Enterprise. Этот инструментарий позволяет быстро освоить экосистему Waves Enterprise, используя любой из языков программирования JVM, поскольку смарт-контракт разворачивается в Docker-контейнере. Вы можете создать смарт-контракт с помощью любого из JVM языков, например Java.
Контракт можно развернуть в различных средах и сетях. Например, для локальной разработки смарт-контрактов и их тестирования вы можете локально развернуть свою сеть (создать локальную среду) на основе ноды в ознакомительном режиме (Sandbox) и развернуть контракты в этой сети.
Вся обработка транзакций осуществляется с помощью методов одного класса, помеченных аннотацией @ContractHandler
. Методы, реализующие логику обработки, помечены @ContractInit
(для CreateContractTx) и @ContractAction
(для CallContractTx).
Для развёртывания контракта необходимо выпустить транзакции 103 и 104.
Системные требования¶
Перед началом разработки смарт-контрактов убедитесь, что на вашей машине установлено следующее ПО:
Docker
JDK версии 8 и выше
Для запуска смарт-контрактов необходимо следующее ПО:
Docker
JRE версии 8 и выше
Зависимости¶
<dependency>
<groupId>com.wavesenterprise</groupId>
<artifactId>we-contract-sdk-grpc</artifactId>
<version>1.0.0</version>
</dependency>
dependencies {
implementation("com.wavesenterprise:we-contract-sdk-grpc:1.0.0")
}
Быстрый старт¶
Для создания вашего нового контракта выполните следующие шаги.
Примечание
Все примеры, приведённые ниже, доступны в разделе Samples GitHub-репозитория Waves Enterprise.
1. Создайте обработчик контрактов¶
@ContractHandler
public class SampleContractHandler {
private final ContractState contractState;
private final ContractTransaction tx;
private final Mapping<List<MySampleContractDto>> mapping;
public SampleContractHandler(ContractState contractState, ContractTransaction tx) {
this.contractState = contractState;
mapping = contractState.getMapping(
new TypeReference<List<MySampleContractDto>>() {
}, "SOME_PREFIX");
this.tx = tx;
}
}
2. Добавьте методы обработки транзакций контракта @ContractInit и @ContractAction¶
public class SampleContractHandler {
// ...
@ContractInit
public void createContract(String initialParam) {
contractState.put("INITIAL_PARAM", initialParam);
}
@ContractAction
public void doSomeAction(String dtoId) {
contractState.put("INITIAL_PARAM", Instant.ofEpochMilli(tx.getTimestamp().getUtcTimestampMillis()));
if (mapping.has(dtoId)) {
throw new IllegalArgumentException("Already has " + dtoId + " on state");
}
mapping.put(dtoId,
Arrays.asList(
new MySampleContractDto("john", 18),
new MySampleContractDto("harry", 54)
));
}
}
3. Отправьте контракт с указанным обработчиком контракта и настройками¶
public class MainDispatch {
public static void main(String[] args) {
ContractDispatcher contractDispatcher = GrpcJacksonContractDispatcherBuilder.builder()
.contractHandlerType(SampleContractHandler.class)
.objectMapper(getObjectMapper())
.build();
contractDispatcher.dispatch();
}
private static ObjectMapper getObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
return objectMapper;
}
}
4. Создайте Docker-образ¶
FROM openjdk:8-alpine
MAINTAINER Waves Enterprise <>
ENV JAVA_MEM="-Xmx256M"
ENV JAVA_OPTS=""
ADD build/libs/*-all.jar app.jar
RUN chmod +x app.jar
RUN eval $SET_ENV_CMD
CMD ["/bin/sh", "-c", "eval ${SET_ENV_CMD} ; java $JAVA_MEM $JAVA_OPTS -jar app.jar"]
5. Отправьте образ в Docker-репозиторий, используемый нодой WE, которая майнит транзакции по контрактам¶
Опубликуйте образ в репозиторий, используемый нодой блокчейн сети Waves Enterprise. Для удобства вы можете использовать bash-скрипт build_and_push_to_docker.sh, который соберёт образ вашего смарт-контракта, опубликует его в указанный реестр и выведет image
и imageHash
на экран.
./build_and_push_to_docker.sh my.registry.com/contracts/my-awesome-docker-contract:1.0.0
6. Подпишите и отправьте в блокчейн транзакции создания и вызова опубликованного смарт-контракта¶
Для создания контракта вам понадобятся image
и imageHash
опубликованного контракта.
Пример CreateContractTx:
{
"image": "my.registry.com/contracts/my-awesome-docker-contract:1.0.0",
"fee": 0,
"imageHash": "d17f6c1823176aa56e0e8184f9c45bc852ee9b076b06a586e40c23abde4d7dfa",
"type": 103,
"params": [
{
"type": "string",
"value": "createContract",
"key": "action"
},
{
"type": "string",
"value": "initialValue",
"key": "createContract"
}
],
"version": 2,
"sender": "3M3ybNZvLG7o7rnM4F7ViRPnDTfVggdfmRX",
"feeAssetId": null,
"contractName": "myAwesomeContract"
}
Для вызова контракта вам понадобится contractId = CreateContractTx.id
.
Пример CallContractTx:
{
"contractId": "7sVc6ybnqZr523xWK5Sg7xADsX597qga8iQNAS9f1D3c",
"fee": 0,
"type": 104,
"params": [
{
"type": "string",
"value": "doSomeAction",
"key": "action"
},
{
"type": "string",
"value": "someValue",
"key": "createContract"
}
],
"version": 2,
"sender": "3M3ybNZvLG7o7rnM4F7ViRPnDTfVggdfmRX",
"feeAssetId": null,
"contractVersion": 1
}
Примечания по использованию¶
Использование с Java 11 и выше¶
Библиотека протестирована с Java 8, 11 и 17. При использовании с Java версии 11 и выше необходимо указать дополнительные опции Java для io.grpc, чтобы включить оптимизацию:
--add-opens java.base/jdk.internal.misc=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED -Dio.netty.tryReflectionSetAccessible=true
Полный пример можно найти в Dockerfile для Java 17.