Como implementar um contrato usando o XVM
Motivação
Todos os desenvolvedores que implementam contratos na Astar Network há muito tempo deveriam ter implementado contratos na EVM primeiro. Isso porque a Astar Network foi a primeira a oferecer suporte a EVM.
Todos os desenvolvedores de contratos que apoiam a Astar Network, incluindo eu, gostariam de implementar contratos com o ink!
Então, você jogará fora o contrato na EVM que implementou no passado? Ou você para o desenvolvimento e não faz nada? Ou você deseja converter todos os contratos implementados em Solidity para Rust?
Nenhuma das opções é boa, certo? Não é necessário dizer que a Astar Network tem diferentes opções. “XVM”.
Com o XVM, você pode operar contratos na EVM a partir do ink! Desta vez, apresentarei como implementar o contrato ink! usando o XVM.
Definitivamente, quero implementar algo usando o XVM no meu próximo hackathon.
ink-xvm-sdk
Primeiro, vamos nos referir ao “ink-xvm-sdk” criado pela equipe principal da Astar Network.
https://github.com/AstarNetwork/ink-xvm-sdk
Como Shunsuke-san da equipe principal disse, e eu concordo, este não é um SDK. Ele seria mais próximo de uma amostra de implementação do que de um SDK.
Vamos dar uma olhada no “ erc20 ”, uma implementação que opera contratos ERC20 na EVM.
https://github.com/AstarNetwork/ink-xvm-sdk/tree/main/contracts/erc20
Vamos dar uma olhada.
Desta vez, explicarei o uso do método “transfer” como uma amostra.
A primeira coisa que quero que você note é o “contratante”.
#[ink(constructor)]
pub fn new(evm_address: [u8; 20]) -> Self {
Self { evm_address }
}
Aqui, o parâmetro é o endereço do contrato “ erc20 ” implantado na EVM. O endereço do contrato na EVM é obrigatório ao lidar com qualquer contrato.
#[ink(message)]
pub fn transfer(&mut self, to: [u8; 20], value: u128) -> bool {
let encoded_input = Self::transfer_encode(to.into(), value.into());
self.env()
.extension()
.xvm_call(
super::EVM_ID,
Vec::from(self.evm_address.as_ref()),
encoded_input,
)
.is_ok()
}
Olhando a próxima função de transferência, ela consiste em duas partes. A primeira é a parte que codifica os dados necessários para chamar usando o Xvm. E a outra é a parte que chama o Xvm em si.
Não verifiquei os detalhes da parte que chama o Xvm, mas posso ver que ela pode ser chamada com um código fixo.
E a parte de codificação é processada por uma função chamada “ transfer_encode ” e parece que ela é implementada para cada função chamada. Agora vamos dar uma olhada nessa função “ transfer_encode ”.
fn transfer_encode(to: H160, value: U256) -> Vec<u8> {
let mut encoded = TRANSFER_SELECTOR.to_vec();
let input = [Token::Address(to), Token::Uint(value)];
encoded.extend(ðabi::encode(&input));
encoded
}
A implementação é relativamente simples.
Converte a constante “ TRANSFER_SELECTOR ” para vec.
Armazena os argumentos “ to ”(para) e “ value ”(valor) da função “ transfer ”(transferir) em uma matriz.
Codifica isso usando o ethabi e adiciona-o ao primeiro vec que você criou.
Há uma coisa que não entendo aqui,e é uma constante chamada “ TRANSFER_SELECTOR ”. Esta definição se parece com isso:
const TRANSFER_SELECTOR: [u8; 4] = hex! ["a9059cbb"];
Este é um seletor fornecido como resultado da compilação do Solidity.
Armazenado no metadata.json como acima.
Etapas para implementar um contrato ink! usando o “ XVM ”
Implementar um construtor com o endereço do contrato na EVM como argumento.
Obter o seletor da função de destino no metadata.json ao compilar o Solidity e defini-lo como uma constante.
Implementar uma função que crie dados codificados para a função a ser chamada.
Implementar a função a ser chamada, criar os dados com a função de codificação e implementar o processo de chamada xvm.
Dessa vez, usei as etapas acima para implementar um contrato xvm que chama o contrato store, que é um exemplo de contrato para o Remix.
#![cfg_attr(not(feature = "std"), no_std)]
/// ID EVM (do runtime astar)
const EVM_ID: u8 = 0x0F;
#[ink::contract(env = xvm_environment::XvmDefaultEnvironment)]
mod store_xvm {
use ethabi::{
ethereum_types::{
H160,
U256,
},
Token,
};
use hex_literal::hex;
use ink::prelude::vec::Vec;
const STORE_SELECTOR: [u8; 4] = hex!["6057361d"];
#[ink(storage)]
pub struct StoreXvm {
evm_address: [u8; 20],
}
impl StoreXvm {
#[ink(constructor)]
pub fn new(evm_address: [u8; 20]) -> Self {
Self { evm_address }
}
#[ink(message)]
pub fn store(&mut self, value: u128) -> bool {
let encoded_input = Self::store_encode( value.into());
self.env()
.extension()
.xvm_call(
super::EVM_ID,
Vec::from(self.evm_address.as_ref()),
encoded_input,
)
.is_ok()
}
fn store_encode(value: U256) -> Vec<u8> {
let mut encoded = STORE_SELECTOR.to_vec();
let input = [Token::Uint(value)];
encoded.extend(ðabi::encode(&input));
encoded
}
}
}
O código fonte completo está disponível neste repositório.
https://github.com/realtakahashi/ink-xvm-sdk
Teste
Inicie o nó local Astar.
% ./astar-collator_4_46 --version
astar-collator_4_46 4.46.1-acaecc594c7
% ./astar-collator_4_46 --dev --tmp
2023-04-21 19:44:13 Astar Collator
2023-04-21 19:44:13 ✌️ version 4.46.1-acaecc594c7
2023-04-21 19:44:13 ❤️ by Stake Technologies <[email protected]>, 2019-2023
Acesse o Remix e compile o contrato “ store ” para garantir que o valor não seja armazenado.
Em seguida, use o Portal Polkadot / Substrate para implantar o contrato ink!.
Em seguida, chame a função “ store ” do Portal Polkadot / Substrate.
se você verificar se o valor está armazenado no lado do Remix, poderá confirmar que o valor definido quando o chamou está armazenado.
Próximo passo
Recentemente, tive a oportunidade de discutir com o Kim Hoon, CTO da Astar Foundation. Ao conversar com ele, percebi novamente o grande valor da Astar Network. Percebi que, usando o XCM, eu poderia integrar a funcionalidade de outras cadeias em meus próprios contratos. A funcionalidade EVM também pode ser integrada usando o XVM. E usando o dapp Staking, você pode criar um aplicativo altamente sustentável obtendo fundos operacionais do dapp. Acreditamos que, usando a Astar Network, podemos criar novos aplicativos que não foram implementados no mundo existente da Web2.
Gostaria de continuar aprendendo a tecnologia Astar Network e transmitindo-a ao maior número possível de pessoas.
Sobre a Astar Network
O futuro dos contratos inteligentes multichain.
A Astar é a plataforma de contrato inteligente mais popular do Japão, suportando ambientes EVM e WebAssembly ( Wasm ) e interoperabilidade entre eles usando uma máquina virtual cruzada. A Astar Network é amigável para todos os tipos de desenvolvedores e para as ferramentas e linguagens que eles já conhecem. Apoiada pela segurança compartilhada da Polkadot, a Astar brilha por si só em um ecossistema vibrante e saudável, e na indústria de blockchain em geral impulsionando a adoção corporativa internacional, e interesse do consumidor em tecnologias Web3.
O sistema Build2Earn da Astar foi projetado para aumentar a rede de maneira inovadora, recompensando simultaneamente participantes e construtores. Ele permite que os desenvolvedores obtenham incentivos para criar e manter seus aplicativos descentralizados, e os usuários obtenham incentivos para apoiar seus projetos favoritos, incentivando o crescimento geral do ecossistema.
Este artigo foi escrito por Realtakahashi Work e traduzido por Adriano P. de Araujo. O original em inglês pode ser encontrado aqui.
Top comments (0)