Escribir en Blockchain
Este contenido ofrece instrucciones detalladas sobre cómo escribir en una blockchain utilizando el Sequence SDK. Explica cómo manejar transacciones de forma asíncrona, incluyendo transacciones en bruto, transferencias de tokens ERC20, ERC721 y ERC1155, así como interacciones con contratos inteligentes.
Escribir en Blockchain
La blockchain puede considerarse como una base de datos de propósito general, pública, visible y verificada. Para escribir en una blockchain, al igual que en una base de datos típica, debe realizar una transacción.
Normalmente, crear una transacción en blockchain es bastante complejo, pero Embedded Wallet se encarga de esa complejidad y expone 5 tipos de Transactions
.
Enviar una transacción es una tarea asíncrona. Puede usar await
al llamar a SequenceWallet.SendTransaction
si desea obtener directamente el objeto TransactionReturn
. O bien, puede optar por la forma recomendada, que es configurar funciones manejadoras para los eventos SequenceWallet.OnSendTransactionComplete
y SequenceWallet.OnSendTransactionFailed
, y llamar al método SequenceWallet.SendTransaction
desde cualquier lugar (sin await). Por ejemplo:
Si no está familiarizado con el trabajo con eventos en Unity, consulte esta excelente publicación en Reddit.
RawTransaction
La forma más básica de una Transaction
, una transacción en bruto, es muy útil para enviar ETH o la moneda de gas de la red con la que está interactuando a una Address
.
Por ejemplo, para enviar un MATIC a 0x9766bf76b2E3e7BCB8c61410A3fC873f1e89b43f
puede usar este fragmento:
donde _wallet es una SequenceWallet.
Nota: el EVM no soporta números de punto flotante. Como resultado, los valores de tokens (y monedas de gas) se representan como números enteros y un valor de “decimales”. 1 ETH (o en el ejemplo anterior, 1 MATIC) se representa como 1000000000000000000
(1 * 10^18), ya que ETH, MATIC y la mayoría de las monedas de gas tienen un valor de “decimales” de 18. DecimalNormalizer.Normalize
(arriba) es una función auxiliar básica que devuelve valor de entrada * 10^decimales
y acepta opcionalmente un valor de “decimales” como segundo parámetro (por defecto 18 si no se proporciona).
Adicionalmente, puede incluir datos en una transacción en bruto en formato hexadecimal como una cadena. Para más información sobre esto, consulte la sección avanzada de esta documentación.
sendERC20
Un token ERC20 es el estándar de tokens fungibles. Puede desplegar fácilmente un contrato ERC20 y mintear tokens usando nuestro Builder. Aprenda cómo hacerlo en nuestra documentación de Builder.
Para enviar una transacción de token ERC20, puede usar este fragmento de código:
Nota: como se mencionó antes, se recomienda usar DecimalNormalizer.Normalize
para convertir el monto de formato legible para humanos a formato EVM. Asegúrese de incluir el parámetro opcional “decimales” (int) si su token ERC20 tiene un valor de “decimales” diferente a 18. Si no está seguro de cuántos “decimales” tiene su ERC20, esto se puede consultar fácilmente en el Builder usando el método “decimals” en “Read Contract”.
Interacciones complejas con ERC20
Para interacciones con tokens ERC20 más allá de transferencias básicas, debe usar nuestra librería SequenceEthereum
incluida en el SDK. Hemos creado funciones envoltorias para contratos inteligentes ERC20 para su conveniencia, que le permiten crear y enviar RawTransactions
con Embedded Wallets.
Primero, debe crear un objeto ERC20
proporcionando una dirección de contrato y, opcionalmente, una cadena ABI, si está usando una variante personalizada del estándar ERC20 (no recomendado).
Con esta referencia, tendrá acceso a todos los métodos implementados por la clase ERC20. Cualquier método que retorne un CallContractFunction
, por ejemplo Mint
, puede usarse al crear una RawTransaction con Embedded Wallets. Por ejemplo:
sendERC721
Un token ERC721 es el estándar no fungible, probablemente los conozca como NFTs. Puede desplegar fácilmente un contrato ERC721 y mintear tokens usando nuestro Builder. Aprenda cómo hacerlo en nuestra documentación de Builder.
Para enviar una transacción de token ERC721, puede usar este fragmento de código:
Interacciones complejas con ERC721
Para interacciones con tokens ERC721 más allá de transferencias básicas, debe usar nuestra librería SequenceEthereum
incluida en el SDK. Hemos creado funciones envoltorias para contratos inteligentes ERC721 para su conveniencia, que le permiten crear y enviar RawTransactions
con Embedded Wallets.
Primero, debe crear un objeto ERC721
proporcionando una dirección de contrato y, opcionalmente, una cadena ABI, si está usando una variante personalizada del estándar ERC721 (no recomendado).
Con esta referencia, tendrá acceso a todos los métodos implementados por la clase ERC721. Cualquier método que retorne un CallContractFunction
, por ejemplo SafeMint
, puede usarse al crear una RawTransaction con Embedded Wallets. Por ejemplo:
sendERC1155
Un token ERC1155 es el estándar multi-token, a menudo llamados SFTs (tokens semi-fungibles). Como co-creadores del estándar ERC1155, creemos firmemente en su utilidad incomparable para juegos. Puede desplegar fácilmente un contrato ERC1155 y mintear tokens usando nuestro Builder. Aprenda cómo hacerlo en nuestra documentación de Builder.
Para enviar una transacción de token ERC1155, puede usar este fragmento de código:
Nota: puede enviar múltiples identificadores de token del mismo contrato ERC1155 en una sola transacción incluyendo varios objetos SendERC1155Values
en la transacción
Interacciones complejas con ERC1155
Para interacciones con tokens ERC1155 más allá de transferencias básicas, debe usar nuestra librería SequenceEthereum
incluida en el SDK. Hemos creado funciones envoltorias para contratos inteligentes ERC1155 para su conveniencia, que le permiten crear y enviar RawTransactions
con Embedded Wallets.
Primero, debe crear un objeto ERC1155
proporcionando una dirección de contrato y, opcionalmente, una cadena ABI, si está usando una variante personalizada del estándar ERC1155 (no recomendado).
Con esta referencia, tendrá acceso a todos los métodos implementados por la clase ERC1155. Cualquier método que retorne un CallContractFunction
, por ejemplo Mint
, puede usarse al crear una RawTransaction con Embedded Wallets. Por ejemplo:
SequenceContractCall
Al llamar a un contrato inteligente en una red basada en EVM, el cliente pasa por un proceso complejo conocido como “codificación ABI”, donde la firma de la función que desea llamar y los parámetros que proporciona se codifican en formato binario. Este proceso es complicado y propenso a errores, así que lo hemos abstraído completamente para que usted no tenga que preocuparse por ello. Pero si tiene curiosidad sobre cómo funciona, consulte este documento.
Una transacción SequenceContractCall le permite llamar cualquier método en un contrato inteligente arbitrario, permitiéndonos manejar el proceso complicado de codificación ABI del lado del servidor.
Para enviar una transacción SequenceContractCall, puede usar este fragmento de código:
Analicemos el ejemplo anterior para comprender mejor algunas de las variables que pueden no ser obvias.
ValueAsString: Esto usualmente será “0” a menos que esté llamando a un método payable denotado por la palabra clave payable
en la definición del contrato inteligente. Si está llamando a un método payable, se recomienda usar DecimalNormalizer.Normalize
para convertir el monto de formato legible para humanos a formato EVM. Tenga en cuenta que el usuario deberá tener los fondos necesarios en su wallet para pagar el valor especificado a una función payable. Este parámetro puede omitirse y tomará el valor por defecto “0”.
FunctionABIAsString: La función con la que planea interactuar. Le recomendamos copiar y pegar la firma de la función (con los parámetros) desde el código fuente del contrato en Etherscan (o el explorador de bloques correspondiente para su red) y eliminar los espacios en blanco y los nombres de las variables.
ParametersAsObjectArray: Los parámetros que desea proporcionar al método que quiere llamar. No es necesario indicar los nombres de los parámetros, solo sus valores en el orden en que aparecen en el ABI. Si tiene dudas, proporcione los parámetros en formato de cadena.
Juntando todo esto, un ejemplo de cómo usar SequenceContractCall
para llamar a la función “mint” en un ERC20 se vería así:
Transacciones en lote
Gracias a la magia del wallet inteligente de Sequence, nuestro SDK le permite agrupar transacciones fácilmente. Agrupar transacciones es muy beneficioso, ya que ahorra gas de manera significativa y le permite crear transacciones complejas que o bien se ejecutan todas o ninguna, sin necesidad de desplegar contratos inteligentes personalizados para cada caso específico, ¡abriendo un mundo de nuevas posibilidades de diseño!
¡Enviar una transacción en lote es sencillo! Solo incluya varias transacciones, de cualquier tipo, en su arreglo de transacciones al hacer la solicitud SendTransaction
.
Por ejemplo: enviar una transacción de cada tipo en un lote:
Como estas transacciones se agrupan en una sola transacción por el wallet inteligente de Sequence antes de enviarse a la red, solo recibirá un recibo de transacción.
FeeOptions
Por defecto, el SDK patrocinará automáticamente todas las transacciones de Embedded Wallet usando sus créditos de la API de Builder. Sin embargo, en algunos casos específicos, puede que prefiera no patrocinar las transacciones de sus usuarios. Esto requiere que sus usuarios sean más experimentados en Web3 y tengan tokens o la moneda de gas en su wallet para pagar las comisiones. Además de la moneda de gas de la red seleccionada, también se pueden pagar las comisiones usando ciertos tokens ERC20 y ERC1155.
Primero, debe preparar la(s) transacción(es) que desea enviar en un lote. Luego, debe obtener las FeeOptions.
La respuesta FeeOptionsResponse
contiene un FeeQuote (cadena) que fija el precio para cada FeeOptionReturn
en el arreglo FeeOptions que se devuelve por un tiempo limitado; necesitará esto en un momento al enviar sus transacciones. Para su comodidad, el SDK consultará automáticamente el wallet del usuario para ver cuáles de las FeeOptions puede pagar usando el Indexer.
A partir de aquí, puede mostrar una interfaz al usuario para que elija cómo desea pagar la comisión de sus transacciones.
Una vez que el usuario haya elegido cómo desea pagar la comisión, puede enviar las transacciones, incluyendo la FeeOption seleccionada y la cadena FeeQuote.
En la Demo Scene
que se puede importar desde Package Manager > Samples
, puede ver un ejemplo básico del uso de FeeOptions. Aquí no se proporciona una interfaz y en su lugar se usa la primera FeeOption disponible en el wallet del usuario. No recomendamos este enfoque en un juego real, pero sirve como ejemplo útil para su propia integración. Vea nuestro código de ejemplo a continuación:
Colas de transacciones
Al trabajar con blockchain, es importante agrupar transacciones para minimizar las comisiones de gas. Para facilitar esto, hemos incluido un TransactionQueuer
flexible en el SDK que puede configurar o extender según sus necesidades. Para aprender más sobre cómo construir juegos con muchas transacciones en Unity y qué considerar, consulte nuestra guía sobre el tema.
Cuando agrega un TransactionQueuer
como MonoBehaviour en su escena, hay algunas variables de configuración que puede ajustar.
AutoSubmitTransactions
: por defecto es falso; si lo habilita, suTransactionQueuer
enviará automáticamente cualquier transacción en cola cuando hayan pasado los segundos definidos enThresholdTimeBetweenTransactionsAddedBeforeSubmittedInSeconds
sin que se agregue una nueva transacción a la cola.ThresholdTimeBetweenTransactionsAddedBeforeSubmittedInSeconds
: siAutoSubmitTransactions == true
, enviará automáticamente las transacciones en cola si no se ha agregado ninguna en los últimosThresholdTimeBetweenTransactionsAddedBeforeSubmittedInSeconds
segundos.MinimumTimeBetweenTransactionSubmissionsInSeconds
: tiempo mínimo entre envíos de transacciones en cola. Con esto, puede llamar aTransactionQueuer.SubmitTransactions()
tantas veces como quiera en su código y las transacciones no se enviarán a menos que hayan pasado los segundos definidos desde el último envío. Nota: si llama aTransactionQueuer.SubmitTransactions(overrideWait: true)
con el parámetro opcionaloverrideWait
en true, elTransactionQueuer
enviará las transacciones en cola sin importar si ha pasado el tiempo mínimo.
El TransactionQueuer
le ofrece varios métodos:
- Setup: antes de llamar a otros métodos en un
TransactionQueuer
, por favor llame aSetup
; esto creará y almacenará en caché las dependencias necesarias. - Enqueue: agrega una transacción a la cola.
- SubmitTransactions(bool overrideWait = false, bool waitForReceipt = true): envía las transacciones en cola si ha pasado el tiempo mínimo desde el último envío por parte del
TransactionQueuer
. SioverrideWait = true
, envía cualquier transacción en cola de inmediato. SiwaitForReceipt = false
, devuelve elTransactionReturn
tan pronto como recibimos respuesta de la WaaS API (nota: esto solo es relevante si la WaaS API se agota esperando el recibo de la transacción; siwaitForReceipt = true
, seguiremos consultando un nodo hasta obtener el recibo antes de devolverlo) - ToString(): una sobreescritura de la función típica ToString(), que proporciona un mejor soporte para logs
Setup
en su TransactionQueuer
!Actualmente, el SDK expone dos herederos diferentes de la clase TransactionQueuer
.
SequenceWalletTransactionQueuer
El SequenceWalletTransactionQueuer
le permite poner en cola transacciones para el Embedded Wallet de Sequence de su usuario.
El SequenceWalletTransactionQueuer
espera que agregue transacciones que implementen la interfaz IQueueableTransaction
. Esta interfaz la implementa la clase QueuedTokenTransaction
. Si lo necesita, puede crear otras clases que implementen la interfaz IQueueableTransaction
.
PermissionedMinterTransactionQueuer
El PermissionedMinterTransactionQueuer
está pensado para poner en cola transacciones que serán enviadas por su servidor backend al recibir un mensaje firmado desde el Embedded Wallet del jugador. Es útil para mintear tokens al wallet del jugador cuando interactúa con contratos que requieren permisos para mintear (la mayoría de los contratos de tokens).
El PermissionedMinterTransactionQueuer
espera que agregue un PermissionedMintTransaction
, un objeto de transferencia de datos básico que especifica el TokenId y la cantidad a mintear, y opcionalmente un IMinter. Si no se proporciona, el PermissionedMinterTransactionQueuer
usará por defecto la clase PermissionedMinter
. La clase PermissionedMinter
será útil para la mayoría de los casos; envía un payload en el siguiente formato:
Luego puede validar este payload en su servidor y mintear el token a la dirección del usuario. Para una implementación y configuración de ejemplo, consulte esta parte de nuestra guía Jelly Forest.
Para otros casos de uso, puede implementar su propia versión de la clase IMinter. Esto le permite modificar el formato y la información que se envía en el payload a su servidor según lo necesite.