diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 9dc1222..bc9c609 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -9,7 +9,13 @@ module.exports = { lang: 'zh-CN', title: 'GXChain文档', description: 'GXChain技术文档' + }, + '/es/': { + lang: 'es-US', + title: 'Documento de GXChain', + description: 'Documento Técnico de GXChain' } + }, head: [ ['link', {rel: 'icon', href: `/logo.png`}], @@ -106,6 +112,47 @@ module.exports = { '/zh/contract/': genSidebarConfig ('contract', '智能合约'), '/zh/ecosystem/': genSidebarConfig ('ecosystem','生态系统') } + }, + '/es/': { + label: 'Español', + selectText: 'Idioma', + editLinkText: 'Edit this page on GitHub', + lastUpdated: 'Last Updated', + serviceWorker: { + updatePopup: { + message: "New content is available.", + buttonText: "Refresh" + } + }, + nav: [ + { + text: 'Guía', + link: '/es/guide/', + }, + // { + // text: 'Tutorial avanzado', + // link: '/es/advanced/', + // }, + { + text: 'Contrato Inteligente', + link: '/es/contract/', + }, + { + text: 'Problemas comunes', + link: '/es/faq/', + // }, + // { + // text: 'Ecosistema', + // link: '/es/ecosystem/', + } + ], + sidebar: { + '/es/guide/': genSidebarConfig ('guide', 'Guía'), + // '/es/advanced/': genSidebarConfig ('contract', 'Tutorial avanzado'), + '/es/contract/': genSidebarConfig ('contract', 'Contrato Inteligente'), + '/es/faq/': genSidebarConfig ('faq', 'Problemas comunes') + // '/es/ecosystem/': genSidebarConfig ('contract', "Ecosistema") + } } } } diff --git a/docs/es/README.md b/docs/es/README.md new file mode 100644 index 0000000..6c78d47 --- /dev/null +++ b/docs/es/README.md @@ -0,0 +1,23 @@ +--- +home: true +heroImage: /hero.png +actionText: Inicio rápido → +actionLink: /zh/guide/ +footer: MIT Licensed | Copyright © 2018 GXChain +--- + +
+
+

Rendimiento Alto

+

Realizar el mecanismo de consenso de DPoS y soporte 3000+ TPS

+
+
+

Latencia Baja

+

Sin desperdicio de esfuerzo minero, bloque autenticación de segundo nivel

+
+
+

Flexible

+

Soporte de contrato inteligente, basado en la máquina virtual estándar WebAssembly

+
+
+ diff --git a/docs/es/contract/README.md b/docs/es/contract/README.md new file mode 100644 index 0000000..f8b4cf6 --- /dev/null +++ b/docs/es/contract/README.md @@ -0,0 +1,898 @@ +# Inicio rápido +## Guía introductoria + +El propósito de este tutorial es proporcionar orientación sobre el desarrollo de contratos inteligentes de GXChain, incluido el desarrollo de contratos, la implementación, la depuración y la categorización de errores comunes. + + +El contrato inteligente GXChain está escrito en lenguaje C++ y desplegado en la red blockchain GXChain después de compilar con la máquina virtual [Webassembly](https://webassembly.org/). Los contratos inteligentes compilados incluyen principalmente el archivo `abi`, que es el archivo de interfaz definido por el contrato, y el archivo fuiste, que es el archivo de código de bytes ejecutado por la máquina virtual webassembly. GXChain utiliza la máquina virtual WebAssembly para admitir contratos inteligentes escritos en varios idiomas, como C + + y TypeScript. + + +**Antes de desarrollar un contrato inteligente, debe hacer lo siguiente:** + +- Conocimiento del desarrollo del lenguaje C++ +- Conocimientos de los comandos del sistema Linux y Mac +- Compile el código fuente localmente, inicie la cadena privada local o conéctese a la red de prueba ([tutorial](https://github.com/gxchain/gxb-core) de compilación de código fuente aquí) + + +**Términos relacionados:** + +- **Acción**:la interfaz externa proporcionada por el contrato inteligente, puede interactuar con el front-end y la `acción` invocada por el usuario se registra en el bloque. +- **Tabla**:el contrato proporciona almacenamiento persistente, similar a la tabla de la base de datos, admite varios índices y la tabla se almacena en el objeto de cuenta de contrato. + +**Introducción de herramientas:** + +- **witness_node**:Un programa de nodo, puede ejecutar diferentes funciones bajo diferentes configuraciones. Por ejemplo, durante el desarrollo del contrato, el puerto RPC se inicia para interactuar con cli_wallet para invocar el contrato a consulta tabla. +- **cli_wallet**:Un programa de billetera de línea de comandos, se utiliza principalmente para administrar la billetera e interactuar con witness_node programa. Los comandos incluyen: contrato de implementación, contrato de llamada, contrato de actualización, tabla de consulta, etc. (utilice el comando `help` y el comando `gethelp` para ver cómo se utiliza la herramienta). +- **gxx**:se utiliza para compilar archivos de `C++` en archivos abi y archivos wasm para su implementación en GXChain. +- **gxc-smart-contract-ide**: a través del IDE de contrato inteligente, puede escribir, compilar, implementar e invocar contratos inteligentes. [Haga clic en la descarga](https://github.com/gxchain/gxchain-alpha/releases/latest). + + +### 1. Inicie la cadena privada local + +Después de la compilación, cambie al directorio donde reside el programa witness_node y utilice el siguiente comando para iniciar el nodo de salida local, los datos para guardar la información de configuración, la información de bloque generada, etc. Inicie el tutorial de cadena privada local haciendo [clic aquí](../advanced/private_chain.md) + +```bash +./witness_node -d data +``` + +Después del inicio, como se muestra en la siguiente figura (registre el ID de la cadena, que cli_wallet utilizará cuando se conecte): + +![](./png/chain_id.jpg) + +Después de ejecutar el nodo de bloque, cambie al directorio cli_wallet y ejecute el siguiente comando para iniciar el cliente cli_wallet para interactuar con el nodo de bloque, incluida la creación de cuentas, la implementación de contratos, la llamada a contratos y otras funciones, que se pueden probados por el cliente cli_wallet. (chain-id cambia a su propio ID) + +```bash +./cli_wallet -sws://localhost:11011 --chain-id=679beed54a9081edfd3ede349a0aa1962ea2dc9d379808fecce56226cb199c84 +``` + +Después del inicio, se ve como este:(Inicio inicial muestra new) + +![](./png/cli_wallet.jpg) + + +### 2. Crear una nueva billetera + +Primero necesitas crear una nueva contraseña para tu billetera, que se usa para desbloquear tu billetera. En el tutorial se utiliza la siguiente contraseña: `supersecret`, también se puede utilizar una combinación de letras y números para crear su propia contraseña. Por favor, introduzca el siguiente comando para crear: + + +```bash +>>> set_password supersecret +``` + +Ahora puedes desbloquear tu billetera recién creada: + +```bash +unlock supersecret +``` + +### 3. reclamar el saldo inicial + +La cuenta de activos se incluye en la cuenta de billetera. Para agregar una cuenta de billetera a tu billetera, debes conocer el nombre de la cuenta y la clave privada de la cuenta. En nuestro ejemplo, importa la cuenta `Nathan` inicializada en my-genesis.json al billetera existente a través del comando `import_key`: + + +```bash +import_key nathan 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 +``` + +::: warning Pronto +* `Nathan` se utilizará para definir el nombre de cuenta en el archivo inicial. Si ha modificado el archivo `my-genesies.json`, puede escribir un nombre diferente. Además, tenga en cuenta que `5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3` es la clave privada definida en el `config.ini` +::: + +Ahora que hemos importado la clave privada en la billetera, la balanza se inicializó en my-genesis.json, debe ser reclamado por el comando `import_balance` sin ninguna tarifa de declaración: + +```bash +import_balance nathan ["5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"] true +``` + +Puede ver su cuenta con el siguiente comando: + +```bash +get_account nathan +``` + +Obtenga el saldo de la cuenta con el siguiente comando: + +```bash +list_account_balances nathan +``` + +### 4. Crear una cuenta + +Ahora vamos a crear una nueva cuenta `alpha` para que podamos transferir dinero de ida y vuelta entre las cuentas de `nathan` y `alpha`. + +Por lo general, utilizamos una cuenta existente para crear una nueva cuenta porque el registrador tiene que pagar una cuota de inscripción. Además, la cuenta del registrador debe entrar en el estado de Also, there is the requirement lifetime member (LTM). Así que tenemos que actualizar la cuenta `Nathan` al estado LTM antes de crear una nueva cuenta, utilizando el comando `upgrade_account` para actualizar la cuenta: + + +```bash +upgrade_account nathan GXC true +``` + +En la información devuelta, encontrará `2106-02-07T06:28:15` junto a `membership_expiration_date`. Si usted ve `1970-01-01T00:00:00`, significa que hay un error en la operación anterior y `nathan` no pudo actualizar con éxito. +Después de la actualización exitosa, podemos registrar la nueva cuenta a través de `nathan`, pero primero necesitamos tener la clave pública de la nueva cuenta. El comando `suggest_brain_key` se utiliza para generar el par de claves pública-privada: + +```bash +// Generar par de claves +suggest_brain_key +``` + +A continuación, llame a la interfaz register\_account/register\_account2 para crear una nueva cuenta + +```bash +register_account alpha GXC6vQtDEgHSickqe9itW8fbFyUrKZK5xsg4FRHzQZ7hStaWqEKhZ GXC6vQtDEgHSickqe9itW8fbFyUrKZK5xsg4FRHzQZ7hStaWqEKhZ nathan nathan 10 true +``` + +Utilice el comando transfer3 para transferir algunos activos a una cuenta + +```bash +transfer3 nathan alpha 1000 GXC test GXC true +``` + +Utilice el siguiente comando para ver el saldo de activos: + +```bash +list_account_balances alpha +``` +## Presentación del contrato Hello World + +Antes de leer este tutorial, supongamos que ha leído la guía introductoria + +### 1. Introducción de la función y llamada de implementación + +#### 1.0 funciones contractuales + +[El contrato Hello World](https://github.com/gxchain/gxb-core/tree/dev_master/contracts/examples/helloworld) es uno de los contratos GXChain más ágiles. Al analizar este contrato, podemos captar el marco básico del desarrollo de contratos inteligentes. El contrato implementa una `acción Hi`, que es la interfaz proporcionada por el contrato a la llamada externa, imprimiendo dos veces el `usuario HI (el parámetro para invocar la acción)` de la cadena a la consola con el siguiente resultado: + + + +![](./png/console_print.jpg) + +#### 1.1 compilación del contrato +El contrato inteligente incluye archivo xxx.hpp y xxx.cpp, que debe compilarse en archivo xxx.wast y xxx.abi antes de que pueda implementarse en la cadena de bloques. Puede compilar archivos wast y abi utilizando la herramienta gxx proporcionada por GXChain, que se puede encontrar en el directorio `~/gxb-core/build/tools/gxx`. Puede cambiar al directorio donde se encuentra gxx y compilar utilizando el siguiente comando: + + +```bash +//compilar archivos wast, reemplace la ruta con su propio +./gxx -o /Users/zhaoxiangfei/code/gxb-core/contracts/examples/helloworld/helloworld.wast /Users/zhaoxiangfei/code/gxb-core/contracts/examples/helloworld/helloworld.cpp + +//compilar archivos abi, reemplace la ruta con su propio +./gxx -g /Users/zhaoxiangfei/code/gxb-core/contracts/examples/helloworld/helloworld.abi /Users/zhaoxiangfei/code/gxb-core/contracts/examples/helloworld/helloworld.hpp +``` +#### 1.2 Implementación del contrato + +Puede usar el siguiente comando para implementar Hello World, Hello para contratar el nombre de usuario (el comando de implementación de contrato creará una cuenta de contrato , los activos de la cuenta de contrato pueden controlar a través de contratos), nathan para pagar la cuenta de tarifas, 0 0 significa máquina virtual tipo y versión, /Users/zhaoxiangfei/code/gxb-core/contracts/examples/helloworld para contratos (**incluyendo archivo wast y abi**), GXC indica el tipo de cuota, y true indica si se emite o no. + +```bash +//implementar el contrato +deploy_contract hello nathan 0 0 /Users/zhaoxiangfei/code/gxb-core/contracts/examples/helloworld GXC true +``` + +::: warning Atención +* Cuando se despliega el contrato, la cuenta que paga la tarifa de manejo debe haber importado la clave privada (el comando anterior paga la cuenta como `Nathan`), y el saldo de la cuenta es suficiente para pagar la tarifa de manejo +::: + +#### 1.3 invocación del contrato + +Puede invocar la interfaz de contrato con el siguiente comando y la interfaz de contrato de invocación de GXChain puede adjuntar la opción de envío de activos. La invocación del activo adicional envía el activo a la cuenta de contrato. Los activos de una cuenta de contrato no se controlan excepto por una API de retirada `withdraw_asset`, que es un código dentro del propio contrato. +```bash +// Los activos no transportados +call_contract nathan hello null hi "{\"user\":\"gxchain!!!\"}" GXC true + +// Activos acumulados (acción para activos acumulados, que se rellenarán en el contrato///@abi pagadero) +call_contract nathan hello {"amount":10000000,"asset_id":1.3.1} hi "{\"user\":\"gxchain!!!\"}" GXC true + +``` + +::: warning Las definiciones de acción con activos transferidos +```cpp +// @abi action +// @abi payable +void hi(std::string user) +{ + { + for (int i = 0; i < 2; ++i) { + print("hi, ", user, "\n"); + } + } +} +``` +::: + +### 2. Análisis de código + +El contrato inteligente Hello World contiene solo una acción, que es el contrato inteligente más simple. Podemos utilizar esto como un ejemplo para analizar el marco básico de los contratos inteligentes. +El desarrollo de contratos implica definir una clase de contrato y proporcionar una interfaz de aplicación que se puede definir mediante el `GRAPHENE_ABI` suministrado por el sistema. + + + +Arriba, se completa un contrato inteligente básico. El directorio del archivo de cabecera es `/Users/zhaoxiangfei/code/gxb-core/contracts/graphenelib` (cambiar a su directorio correspondiente), durante el desarrollo de contrato, después de introducir el archivo de cabecera relevante, puede utilizar los tipos integrados y funciones integradas de api de contratos. El siguiente tutorial analiza un contrato inteligente más complejo-el contrato de envolventes rojos. + + + +## Presentación al contrato de Bolsos Rojos + +Antes de leer este tutorial, supongamos que ha leído la guía introductoria + +### 1. Introducción de la función y llamada de implementación + +#### 1.0 funciones contractuales + +[El contrato de Bolsos Rojos](https://github.com/gxchain/gxb-core/tree/dev_master/contracts/examples/redpacket) es un contrato relativamente complejo. A través del análisis del contrato de Bolsos Rojos, explicaremos el uso de la tabla multi-índice, la llamada API incorporada y otras funciones. + +El contrato de Bolsos Rojos consta de tres acciones: emitir(issue), abrir(open) y cerrar(close). +> Nota: la llamada cree la interfaz del bolso rojo (issue) se puede asociar los activos; si los bolsos rojos no se ajustan, el emisor puede cerrarlo y devolver el saldo. Debe establecer una contraseña (clave pública) para enviar un bolso rojo. Para poder agarrar un bolso rojo, usted necesita firmar su ID de usuario con la clave privada correspondiente a la contraseña. + + +- **Llamar la interfaz para enviar bolso rojo, el proceso y los resultados de la retroalimentación como el siguiente:** +```bash +# pubkey es una contraseña generada aleatoriamente: la siguiente llamada significa que se envían 5 bolsos rojos con una cantidad total de 11 GXC (1.3.1 significa activos GXC) +unlocked >>> call_contract nathan redpacket {"amount":1100000,"asset_id":1.3.1} issue "{\"pubkey\":\"GXC81z4c6gEHw57TxHfZyzjA52djZzYGX7KN8sJQcDyg6yitwov5b\",\"number\":5}" GXC true +{ + "ref_block_num": 15124, + ... + ... + ... + "signatures": [ + "1f7fade01ef08d986282164c1428fee37ecc5817c4e6bdc7c160220cf965b881d7417874ab22be48047becf62936e6a060a3e06c65e3548e90a72ddc1720794db3" + ] +} +# Compruebe los activos de la cuenta de contrato, en el contrato actual sólo hay un usuario enviando bolsos rojos, por lo que la cantidad de un activo enviado por un usuario 11 GXC +unlocked >>> list_account_balances redpacket +11 GXC + +# Para la información de la tabla de los paquetes rojos, los subpaquetes se dividen aleatoriamente en 5 secuencias de paquetes rojos, y el pub_key se utiliza para verificar la firma +unlocked >>> get_table_rows redpacket packet 0 -1 +[{ + "issuer": 17, + "pub_key": "GXC81z4c6gEHw57TxHfZyzjA52djZzYGX7KN8sJQcDyg6yitwov5b", + "total_amount": { + "amount": 1100000, + "asset_id": 1 + }, + "number": 5, + "subpackets": [ + 350531, + 150227, + 390591, + 66767, + 141884 + ] + } +] + +``` + +Para agarrar un bolso rojo, es necesario conocer la clave privada correspondiente a la contraseña de envío de un bolso rojo. Los bolsos rojos de pelo se crean cuando la contraseña es: GXC81z4c6gEHw57TxHfZyzjA52djZzYGX7KN8sJQcDyg6yitwov5b, debe conocer la contraseña de la clave privada correspondiente (la contraseña de clave privada es 5j9vj4xiwvq2hnr22ufrxgaaerqrpn7xzqer9z2hwspewdbmkbm). El método sign_string se proporciona mediante cli_wallet. El Instance ID es el último campo del ID de cuenta. Por ejemplo, el ID de cuenta de Nathan es 1.2.17, por lo que su Instance ID es 17. + + +- **Llame para agarrar un bolso rojo, el proceso y los resultados de la retroalimentación como sigue:** +```bash +#firmar el Instance ID utilizando la clave privada +unlocked >>> get_account_id nathan +"1.2.17" +unlocked >>> sign_string 5J9vj4XiwVQ2HNr22uFrxgaaerqrPN7xZQER9z2hwSPeWdbMKBM 17 +"1f1d104d5750beba9fd4b0637ce69cf54721a57cce91ca81904653307eb72b0a840bd8a80c58df0a7be206a4c5c5b1fa0d96d497667e54579e717d499d0a3498b2" + +#Llame para agarrar un bolso rojo +call_contract nathan redpacket null open "{\"issuer\":\"nathan\",\"sig\":\"1f1d104d5750beba9fd4b0637ce69cf54721a57cce91ca81904653307eb72b0a840bd8a80c58df0a7be206a4c5c5b1fa0d96d497667e54579e717d499d0a3498b2\"}" GXC true +#saldo de la cuanta del contrato inteligente +list_account_balances redpacket +unlocked >>> list_account_balances redpacket +7.09409 GXC +#La secuencia de distribución de los bolsos rojos restantes en la cuenta de contrato se reduce de 5 a 4, y el artículo reducido es 390591, lo que representa la pérdida de 3,90591 GXC +unlocked >>> get_table_rows redpacket packet 0 -1 +[{ + "issuer": 17, + "pub_key": "GXC81z4c6gEHw57TxHfZyzjA52djZzYGX7KN8sJQcDyg6yitwov5b", + "total_amount": { + "amount": 1100000, + "asset_id": 1 + }, + "number": 5, + "subpackets": [ + 350531, + 150227, + 66767, + 141884 + ] + } +] +# el registro de agarrar bolsos rojos +unlocked >>> get_table_rows redpacket record 0 -1 +[{ + "packet_issuer": 17, + "accounts": [{ + "account_id": 17, + "amount": 390591 + } + ] + } +] + +``` + +- **La llamada de interfaz para cerrar el bolso rojo, a la que solo puede llamar el usuario que envió el bolso rojo. El bolso rojo sin terminar será devuelto al usuario. El proceso de llamada y los comentarios de resultados son los siguientes** + +```bash +# Puede cerrar el bolso rojo mediante el siguiente comando +unlocked >>> call_contract nathan redpacket null close "{}" GXC true + +# Obtener el saldo de activos de la cuenta de contrato +unlocked >>> list_account_balances redpacket +0 GXC +``` + +#### 1.1 Compilación del contrato + +Puede compilar el archivo abi y el archivo wast para el contrato inteligente mediante el siguiente comando: + +```bash +# Donde redpacket.cpp se encuentra, es necesario reemplazarlo con su propia ruta de acceso +./gxx -g /Users/zhaoxiangfei/code/gxb-core/contracts/examples/redpacket/redpacket.abi /Users/zhaoxiangfei/code/gxb-core/contracts/examples/redpacket/redpacket.cpp + +# Donde redpacket.cpp se encuentra, es necesario reemplazarlo con su propia ruta de acceso +./gxx -o /Users/zhaoxiangfei/code/gxb-core/contracts/examples/redpacket/redpacket.wast /Users/zhaoxiangfei/code/gxb-core/contracts/examples/redpacket/redpacket.cpp +``` + +#### 1.2 Implementación del contrato + +Puede utilizar el siguiente comando para implementar el contrato Bolsos Rojos + +```bash +# Debe reemplazar la ruta de acceso donde reside el contrato inteligente con su propia ruta de acceso +deploy_contract redpacket nathan 0 0 /Users/zhaoxiangfei/code/gxb-core/contracts/examples/redpacket GXC true +``` + +#### 1.3 Invocación del contrato + +```bash +# enviar bolso rojo +unlocked >>> call_contract nathan redpacket {"amount":1100000,"asset_id":1.3.1} issue "{\"pubkey\":\"GXC81z4c6gEHw57TxHfZyzjA52djZzYGX7KN8sJQcDyg6yitwov5b\",\"number\":5}" GXC true + +# agarrar bolso rojo +unlocked >>> call_contract nathan redpacket null open "{\"issuer\":\"nathan\",\"sig\":\"1f1d104d5750beba9fd4b0637ce69cf54721a57cce91ca81904653307eb72b0a840bd8a80c58df0a7be206a4c5c5b1fa0d96d497667e54579e717d499d0a3498b2\"}" GXC true + +# puede utilizar el siguiente comando para cerrar bolso rojo +unlocked >>> call_contract nathan redpacket null close "{}" GXC true +``` + +### 2. Análisis de código + +El código de contrato Bolso Rojo contiene llamadas a la api integrada y el uso de tablas de varios índices. Analizando los contratos Bolso Rojo, vamos a explicar brevemente cómo usarlos. El marco del contrato se puede encontrar en la introducción al contrato Hello World en el tutorial anterior. + +- nota //@abi payable significa que la acción se puede cargar con activos para producir los archivos abi correctos +```cpp +// @abi action +// @abi payable +void issue(std::string pubkey, uint64_t number){ + ... +} +``` + +- Utilizar graphene_assert, revertir la acción cuando falle +```cpp +graphene_assert(pubkey.size() > prefix_len, "invalid public key"); +graphene_assert(pubkey.substr(0, prefix_len) == prefix, "invalid public key"); +``` + +- Llamar a la API integrada +```cpp +//Importar archivo de encabezado relacionado, api integrada documento, por favor haga clic en¨api integrada +int64_t total_amount = get_action_asset_amount(); +``` + +- Una breve introducción a las tablas de varios índices + +```cpp +//Cada tabla de índice múltiple se denomina tabla y, en el desarrollo del contrato, se define como una clase. +//La sección de comentarios se utiliza para generar el archivo abi. Consulte la sección Detalles del archivoabi para obtener más información. +//@abi table packet i64 +struct packet { + uint64_t issuer; + std::string pub_key; + contract_asset total_amount; + uint32_t number; + vector subpackets; // 可以定义复杂类型 + + uint64_t primary_key() const { return issuer; } // 定义一个主键函数,返回的值作为主键索引是唯一的。 + + GRAPHENE_SERIALIZE(packet, (issuer)(pub_key)(total_amount)(number)(subpackets)) +}; + +//Definar el tipo de tabla de índice múltiple +typedef graphene::multi_index packet_index; +//Declarar una instancia del tipo de tabla multi-indexado +packet_index packets; + +//Aumentar +packets.emplace(owner, [&](auto &o) { + o.issuer = owner; + ... +}); + +//Modificar +packets.modify(packet_iter, sender, [&](auto &o) { + o.subpackets.erase(subpacket_it); +}); + +//Eliminar +packets.erase(packet_iter); +``` +## Presentación al contrato de bank + + +Antes de leer este tutorial, supongamos que ha leído la guía introductoria + +### 1. Introducción de la función y llamada de implementación + +#### 1.0 funciones contractuales + +[El contrato bank](https://github.com/gxchain/gxb-core/tree/dev_master/contracts/examples/bank) proporciona acceso a los tokens. Hay dos interfaces de acción, una para la interfaz de almacenamiento. Cuando el usuario llama a la interfaz, el recurso de token adicional es el activo que el usuario necesita almacenar. La segunda es la interfaz de retirada, que especifica el retiro de un cierto número de activos a una cuenta especificada. Contiene una `account table` que almacena el ID de usuario y la lista de activos que almacena. + + + +- **llama a la interfaz de activos almacenados, el proceso y los resultados de la retroalimentación como el siguiente:** +```bash +//Nathan llama a la interfaz de deposit para almacenar 10GXC en el contrato bank +unlocked >>> call_contract nathan bank {"amount":1000000,"asset_id":1.3.1} deposit "{}" GXC true +{ + { + "ref_block_num": 36472, + "ref_block_prefix": 290922209, + "expiration": "2018-11-20T09:19:40", + "operations": [[ + ... + ... +} +//Vea la tabla de cuentas en el contrato para obtener los activos almacenados en la cuenta, el asset_id representa GXC, el propietario es ID de instancia y 17 representa la cuenta Nathan +unlocked >>> get_table_rows bank account 0 -1 +[{ + "owner": 17, + "balances": [{ + "amount": 1000000, + "asset_id": 1 + } + ] + } +] +``` +- **llamar a la interfaz de retirada de activos, el proceso y los resultados de la retroalimentación como el siguiente:** + +```bash +//nathan llamar a la interfaz de retirada de activos,Retira 1GXC a tu cuenta de Hello. +unlocked >>> call_contract nathan bank null withdraw "{\"to_account\":\"hello\",\"amount\":{\"asset_id\":1,\"amount\":100000}}" GXC true +{ + "ref_block_num": 36733, + "ref_block_prefix": 1321509121, + "expiration": "2018-11-20T09:42:10", + ... + ... +} +//ver el saldo de activos de la cuanta Hello después de retirada +unlocked >>> list_account_balances hello +1 GXC +``` +#### 1.1 Compilación del contrato + +Puede compilar el archivo abi y el archivo wast para el contrato inteligente mediante el siguiente comando: + +```bash +# Donde bank.cpp se encuentra, es necesario reemplazarlo con su propia ruta de acceso +./gxx -g /Users/zhaoxiangfei/code/contracts_work/bank/bank.abi /Users/zhaoxiangfei/code/contracts_work/bank/bank.cpp + +# Donde bank.cpp se encuentra, es necesario reemplazarlo con su propia ruta de acceso +./gxx -o /Users/zhaoxiangfei/code/contracts_work/bank/bank.wast /Users/zhaoxiangfei/code/contracts_work/bank/bank.cpp +``` + +#### 1.2 Implementación del contrato + +Puede utilizar el siguiente comando para implementar el contrato bank + +```bash +# Debe reemplazar la ruta de acceso donde reside el contrato inteligente con su propia ruta de acceso +deploy_contract bank nathan 0 0 /Users/zhaoxiangfei/code/contracts_work/bank GXC true +``` + +#### 1.3 Invocación del contrato + +```bash +# método de invocar la interfaz de los activos de almacenamiento +call_contract nathan bank {"amount":1000000,"asset_id":1.3.1} deposit "{}" GXC true + +# método de invocar la interfaz de los activos de retirada +call_contract nathan bank null withdraw "{\"to_account\":\"hello\",\"amount\":{\"asset_id\":1,\"amount\":100000}}" GXC true +``` + +### 2.Análisis de código + +El contrato bank incluye dos interfaces de acción y una tabla. Este tutorial se centra en la implementación de la lógica funcional del contrato. +Una tabla que almacena el ID de usuario y la lista de activos +```cpp +//La clave principal es el instance_id de usuario, el campo debalances es la lista de activos almacenados del usuario +//@abi table account i64 +struct account { + uint64_t owner; + std::vector balances; //tipo complejo vector, el elemento es el tipo integrado contract_asset + + uint64_t primary_key() const { return owner; } + + GRAPHENE_SERIALIZE(account, (owner)(balances)) +}; +``` +La action que almacena el activo, que no tiene parámetros. Si desea llamar a esta interfaz para almacenar activos, hágalo transfiriendo activos adicionales. La función lógica de la interfaz es obtener información adicional del activo (ID de activo, número de activos), atravesar table account persistente y añadir la información del activo almacenado a la tabla. + +:::warning Nota +Al modificar los campos de la tabla, debe llamar a la interfaz de modify proporcionada por GXChain. No puede modificar directamente el iterador obtenido a través del recorrido. El tipo de iterador devuelto por el método Find es const. +::: +```cpp +// payable se usa para nombrar la tabla: los activos se pueden adjuntar cuando se llama a la acción +// @abi action +// @abi payable +void deposit() +{ + // Get_action_asset_amount y get_action_asset_id se utilizan para obtener el ID de activo adicional y el número de activos cuando se llama a la acción + int64_t asset_amount = get_action_asset_amount(); + uint64_t asset_id = get_action_asset_id(); + contract_asset amount{asset_amount, asset_id}; + + // Obtiene el identificador de llamada + uint64_t owner = get_trx_sender(); + auto it = accounts.find(owner); + //Si el llamador aún no ha almacenado el activo, se crea un elemento de tabla para él, con la clave principal siendo el usuario instance_id + if (it == accounts.end()) { + accounts.emplace(owner, [&](auto &o) { + o.owner = owner; + o.balances.emplace_back(amount); + }); + } else { + uint16_t asset_index = std::distance(it->balances.begin(), + find_if(it->balances.begin(), it->balances.end(), [&](const auto &a) { return a.asset_id == asset_id; })); + if (asset_index < it->balances.size()) { + // La clase contract_asset sobrecarga el operador + =, que puede agregar directamente cuando el usuario continúa almacenando en el recurso + accounts.modify(it, 0, [&](auto &o) { o.balances[asset_index] += amount; }); + } else { + accounts.modify(it, 0, [&](auto &o) { o.balances.emplace_back(amount); }); + } + } +} + +``` + +La acción para retirar activos, la interfaz tiene dos parámetros. El primer parámetro es el nombre de cuenta ( no es ID de cuenta) y el segundo activo es el activo de retirar (ID de activo y cantidad de retiro). La función de esta función es una forma de retirar un activo de un contrato en una cuenta especificada llamando a la api de retirada integrada (withdraw_asset) después de que se pase una solicitud validada. Para las funciones detalladas, consulte las siguientes notas: +```cpp +// @abi action +void withdraw(std::string to_account, contract_asset amount) +{ + //Obtiene el usuario instance_id en función del nombre de usuario, que es la cuenta a la que se requiere el efectivo + int64_t account_id = get_account_id(to_account.c_str(), to_account.size()); + graphene_assert(account_id >= 0, "invalid account_name to_account"); + graphene_assert(amount.amount > 0, "invalid amount"); + + // Obtiene el identificador de la llamada + uint64_t owner = get_trx_sender(); + auto it = accounts.find(owner); + graphene_assert(it != accounts.end(), "owner has no asset"); + + int asset_index = 0; + for (auto asset_it = it->balances.begin(); asset_it != it->balances.end(); ++asset_it) { + if ((amount.asset_id) == asset_it->asset_id) { + graphene_assert(asset_it->amount >= amount.amount, "balance not enough"); + if (asset_it->amount == amount.amount) { + //Cuando el usuario finaliza la extracción de un activo, el activo de la lista se vacía + accounts.modify(it, 0, [&](auto &o) { + o.balances.erase(asset_it); + }); + //Cuando la lista de activos de usuario está vacía, es decir, el usuario retira todos los activos y vacía la lista de usuarios + if (it->balances.size() == 0) { + accounts.erase(it); + } + } else { + accounts.modify(it, 0, [&](auto &o) { + o.balances[asset_index] -= amount; + }); + } + break; + } + asset_index++; + } + //api incorporada, retirada de activos a la cuenta especificada + withdraw_asset(_self, account_id, amount.asset_id, amount.amount); +} +``` +## Presentación al contrato de riddle + +Antes de leer este tutorial, supongamos que ha leído la guía introductoria + +### 1. Introducción de la función y llamada de implementación + +#### 1.0 funciones contractuales + + +[El contrato de riddle](https://github.com/gxchain/gxb-core/tree/dev_master/contracts/examples/riddle) es un contrato de adivinanzas que consta de dos interfaces de action y una table. A través de la interfaz de issue, los usuarios pueden crear un valor hash del puzzle y responder y guardarlo en la cadena de bloques. La interfaz reveal se utiliza para verificar si la respuesta del puzzle es correcta, es decir, si el valor hash de la respuesta es consistente con el valor hash correspondiente a la respuesta del puzzle. + +- **Crear puzles y respuestas hash** + +```bash +//Genere el valor hash sha256 correspondiente a la respuesta, y la respuesta está en texto claro 4 +zhaoxiangfei@zhaoxiangfeideMacBook-Pro:~$ echo -n "4" | shasum -a 256 +4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a + +//crear un contenido para`2+2=?`acertijo, la respuesta es 4 +unlocked >>> call_contract nathan riddle null issue "{\"question\":\"2 + 2 = ?\", \"hashed_answer\":\"4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a\"}" GXC true +{ + "ref_block_num": 39138, + "ref_block_prefix": 3499868408, + "expiration": "2018-11-20T13:37:00", + "operations": [[ + 75,{ + "fee": { + "amount": 100, + "asset_id": "1.3.1" + }, + "account": "1.2.17", + "contract_id": "1.2.29", + "method_name": "issue", + "data": "0932202b2032203d203f4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a", + "extensions": [] + } + ] + ], + "extensions": [], + "signatures": [ + "1f0982608581765be0119c2af2261dd161b60e9ff5f02d07ff69c486e0ef2e52ef3187544f035d169de640386c87e24f2c61194693ac82d708f6177745d6dfb5a5" + ] +} +``` +- **Compruebe que la respuesta enviada es correcta o falsa y la salida de éxito o error** + +Compruebe la respuesta enviada, envío de errores, la consola se muestra de la siguiente manera: +![](./png/wrong_answer.jpg) +Compruebe la respuesta enviada, envío de éxitos, la consola se muestra de la siguiente manera: +![](./png/right_answer.jpg) + +#### 1.1 Compilación del contrato + +Puede compilar el archivo abi y el archivo wast para el contrato inteligente mediante el siguiente comando: + +```bash +# Donde iddle.cpp se encuentra, es necesario reemplazarlo con su propia ruta de acceso +./gxx -g /Users/zhaoxiangfei/code/contracts_work/riddle/riddle.abi /Users/zhaoxiangfei/code/contracts_work/riddle/riddle.cpp + +# Donde iddle.cpp se encuentra, es necesario reemplazarlo con su propia ruta de acceso +./gxx -o /Users/zhaoxiangfei/code/contracts_work/riddle/riddle.wast /Users/zhaoxiangfei/code/contracts_work/riddle/riddle.cpp +``` + +#### 1.2 Implementación del contrato + +Puede utilizar el siguiente comando para implementar el contrato riddle + +```bash +# Debe reemplazar la ruta de acceso donde reside el contrato inteligente con su propia ruta de acceso +deploy_contract riddle nathan 0 0 /Users/zhaoxiangfei/code/contracts_work/riddle GXC true +``` + +#### 1.3 Invocación del contrato + +```bash +# Genere el hash sha256 de la respuesta +echo -n "4" | shasum -a 256 +# Crea un hash del puzzle y responde +call_contract nathan riddle null issue "{\"question\":\"2 + 2 = ?\", \"hashed_answer\":\"4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a\"}" GXC true + +# Enviar la forma en que la respuesta del rompecabezas se llama +# Respuesta equivocada +call_contract nathan riddle null reveal "{\"issuer\":\"nathan\", \"answer\":\"3\"}" GXC true +# Respuesta correcta +call_contract nathan riddle null reveal "{\"issuer\":\"nathan\", \"answer\":\"4\"}" GXC true +``` + +### 2.Análisis de código + +El contrato incluye una tabla para almacenar el valor hash del puzzle y la respuesta, y cuando se resuelve el puzzle, los elementos resueltos en la tabla se borran. La clave principal de la tabla es issuer(instance_id), debido a la clave principal es única, por lo que cada usuario sólo puede crear un puzzle en la cadena al mismo tiempo. Incluye dos acciones que crean puzzles y envían respuestas. La respuesta al puzzle se almacena como un hash en la tabla. + + +```cpp +// @abi table record i64 +struct record { + uint64_t issuer; //La clave principal es única y no se puede utilizar si un usuario crea varios puzzles + std::string question; + checksum256 hashed_answer; //checksum256 el tipo de valor hash integrado + + uint64_t primary_key() const { return issuer; } + + GRAPHENE_SERIALIZE(record, (issuer)(question)(hashed_answer)) +}; +``` + +- Crear el rompecabezas, enviar el texto claro del rompecabezas y el valor hash de la respuesta, el valor hash debe generarse bajo la operación de cadena, utilizando el algoritmo sha256 para generar el hash +```cpp +/// @abi action +void issue(const std::string& question, const checksum256& hashed_answer) +{ + // Obtiene el instance_id del llamador como la clave principal de la tabla de registro + uint64_t owner = get_trx_sender(); + records.emplace(owner, [&](auto &p) { + p.issuer = owner; + p.question = question; + p.hashed_answer = hashed_answer; + }); +} +``` +- La respuesta enviada es verificada por el contrato. El método sha256 está integrado en el contrato, que puede comprobar si la respuesta enviada cumple las condiciones de la cadena +```cpp +/// @abi action +void reveal(const std::string& issuer, const std::string& answer) +{ + int64_t issuer_id = get_account_id(issuer.c_str(), issuer.size()); + graphene_assert(issuer_id >= 0, "issuer not exist"); + auto iter = records.find(issuer_id); + graphene_assert(iter != records.end(), "no record"); + + // sha256 verifica que la respuesta enviada es correcta + checksum256 hashed_answer; + sha256(const_cast(answer.c_str()), answer.length(), &hashed_answer); + + // Cuando el puzzle está agrietado, se elimina de la tabla y la memoria se recupera + if (iter->hashed_answer == hashed_answer) { + print("reveal success! \n"); + records.erase(iter); + } else { + print("answer is wrong! \n"); + } +} +``` + +## Presentación al contrato de linear\_vesting\_asset + +Antes de leer este tutorial, supongamos que ha leído la guía introductoria + +### 1. Introducción de la función y llamada de implementación + +#### 1.0 funciones contractuales + +El contrato [linear_vesting_asset](https://github.com/gxchain/gxb-core/tree/dev_master/contracts/examples/linear_vesting_asset) básicamente mantiene la liberación lineal de un activo a una cuenta a tiempo. El usuario puede crear una entrada de liberación de activos que contenga la cuenta que recibió el activo liberado, el tiempo de congelación y la hora de lanzamiento. Descripción: la cuenta a libera un activo linealmente a la cuenta B mediante un contrato. Después de congelar XX tiempo (XX significa tiempo de congelación) se puede especificar, se puede iniciar la liberación. Se libera el tiempo total (XX significa tiempo de liberación) y la liberación del activo es lineal. + + +- **创建线性释放资产项** +```bash +// Cree un elemento de liberación de activos lineales en la cuenta Hello, congelando durante 30 años y liberando 120s +call_contract nathan vesting {"amount":1000000,"asset_id":1.3.1} vestingcreate "{\"to\":\"hello\",\"lock_duration\":30,\"release_duration\":120}" GXC true +unlocked >>> get_table_rows vesting vestingrule 0 -1 +[{ + "account_id": 22, + "vesting_amount": 1000000, + "vested_amount": 0, + "lock_time_point": 1542785150, + "lock_duration": 30, + "release_time_point": 1542785180, + "release_duration": 120 + } +] +``` +- **Contrato de descongelación lineal** + +```bash +// Descongelar activos en la cuenta Hello +unlocked >>> call_contract nathan vesting null vestingclaim "{\"who\":\"hello\"}" GXC true +unlocked >>> list_account_balances hello +11 GXC +``` +#### 1.1 Compilación del contrato + +Puede compilar el archivo abi y el archivo wast para el contrato inteligente mediante el siguiente comando: + +```bash +# Donde linear_vesting_asset.cpp se encuentra, es necesario reemplazarlo con su propia ruta de acceso +./gxx -g /Users/zhaoxiangfei/code/contracts_work/linear_vesting_asset/linear_vesting_asset.abi /Users/zhaoxiangfei/code/contracts_work/linear_vesting_asset/linear_vesting_asset.cpp + +# Donde linear_vesting_asset.cpp se encuentra, es necesario reemplazarlo con su propia ruta de acceso +./gxx -o /Users/zhaoxiangfei/code/contracts_work/linear_vesting_asset/linear_vesting_asset.wast /Users/zhaoxiangfei/code/contracts_work/linear_vesting_asset/linear_vesting_asset.cpp +``` + +#### 1.2 Implementación del contrato + +Puede utilizar el siguiente comando para implementar el contrato vesting + +```bash +# Debe reemplazar la ruta de acceso donde reside el contrato inteligente con su propia ruta de acceso +deploy_contract vesting nathan 0 0 /Users/zhaoxiangfei/code/contracts_work/linear_vesting_asset GXC true +``` + +#### 1.3 Invocación del contrato + +```bash +// El nombre del contrato es Vesting, el activo adicional es 10 GXC (el ID del activo es 1.3.1), la cuenta liberada es cuenta de saludo, la versión comienza después del congelamiento de los 30s, y todos los activos se completan completamente después de 120S. +call_contract nathan vesting {"amount":1000000,"asset_id":1.3.1} vestingcreate "{\"to\":\"hello\",\"lock_duration\":30,\"release_duration\":120}" GXC true + +// Reclamar activos liberados a la cuenta de Hello (sólo se puede reclamar después de los años 30, que es el tiempo de congelación) +call_contract nathan vesting null vestingclaim "{\"who\":\"hello\"}" GXC true +``` + +### 2.Análisis de código +- El contrato contiene una tabla (vestingrule, tienda persistente que sostiene el número de activos bloqueados, tiempo de bloqueo, tiempo de liberación, etc.) +```cpp +//@abi table vestingrule i64 +struct vestingrule { + uint64_t account_id; //Reclame la clave principal ID de la cuenta. No puede tener dos elementos liberando activos en la misma cuenta al mismo tiempo + + int64_t vesting_amount; //Activo bloqueado inicial + int64_t vested_amount; //Los activos liberados + + int64_t lock_time_point; //Hora de inicio de bloqueo + int64_t lock_duration; //Cuánto tiempo el bloqueo comienza a liberar + int64_t release_time_point; //Hora de inicio de liberar + int64_t release_duration; //Cuánto tiempo para liberar todos + + uint64_t primary_key() const { return account_id; } + + GRAPHENE_SERIALIZE(vestingrule, + (account_id)(vesting_amount)(vested_amount)(lock_time_point)(lock_duration)(release_time_point)(release_duration)) +}; +``` + +- Contiene dos action (vestingcreate action para crear un elemento de activo de liberación lineal; vestingclaim action para reclamar activos liberados linealmente) + +```cpp +/// @abi action +/// @abi payable +void vestingcreate(std::string to, int64_t lock_duration, int64_t release_duration) +{ + // ccontract_asset_id es una variable personalizada que representa un activo GXC, y un activo de liberación lineal solo admite GXC es una variable personalizada que representa un activo GXC, y un activo de liberación lineal solo admite GXC + graphene_assert(contract_asset_id == get_action_asset_id(), "not supported asset"); + contract_asset ast{get_action_asset_amount(), contract_asset_id}; + int64_t to_account_id = get_account_id(to.c_str(), to.size()); + // Compruebe que la cuenta de reclamación es válida y que la cuenta de reclamación tiene activos bloqueados + graphene_assert(to_account_id >= 0, "invalid account_name to"); + auto lr = vestingrules.find(to_account_id); + graphene_assert(lr == vestingrules.end(), "have been locked, can only lock one time"); + + //Cree un elemento de liberación de activos, añada un elemento a la tabla vestingrule y utilice la interfaz emplace + vestingrules.emplace(0, [&](auto &o) { + o.account_id = to_account_id; + o.vesting_amount = ast.amount; + o.vested_amount = 0; + o.lock_time_point = get_head_block_time(); + o.lock_duration = lock_duration; + o.release_time_point = o.lock_time_point + o.lock_duration; + o.release_duration = release_duration; + }); +} + +/// @abi action +void vestingclaim(std::string who) +{ + // Compruebe que el ID de cuenta reclamado es válido + int64_t who_account_id = get_account_id(who.c_str(), who.size()); + graphene_assert(who_account_id >= 0, "invalid account_name to"); + + // Compruebe que en la cuenta hay activos que están bloqueados para la + auto lr = vestingrules.find(who_account_id); + graphene_assert(lr != vestingrules.end(), "current account have no locked asset"); + + // Compruebe que el activo se ha congelado y cuente el número de activos que se pueden reclamar + uint64_t now = get_head_block_time(); + graphene_assert(now > lr->release_time_point, "within lock duration, can not release"); + int percentage = (now - lr->release_time_point) * 100 / lr->release_duration; + if (percentage > 100) + percentage = 100; + int64_t vested_amount = (int64_t)(1.0f * lr->vesting_amount * percentage / 100); + vested_amount = vested_amount - lr->vested_amount; + graphene_assert(vested_amount > 0, "vested amount must > 0"); + + // Retirar activos para reclamar la cuenta reclamada + withdraw_asset(_self, who_account_id, contract_asset_id, vested_amount); + + // Después de la retirada, modifique los campos vesting_amount、 vested_amount del elemento de notificación de activos + vestingrules.modify(lr, 0, [&](auto &o) { + o.vested_amount += vested_amount; + }); + if (lr->vesting_amount == lr->vested_amount) { + vestingrules.erase(lr); + } +} +``` + + + + + + diff --git a/docs/es/contract/abi.md b/docs/es/contract/abi.md new file mode 100644 index 0000000..29bc5bd --- /dev/null +++ b/docs/es/contract/abi.md @@ -0,0 +1,103 @@ + +# Análisis de archivos ABI + + +El archivo abi es la interfaz externa para invocar la action de contrato inteligente, definiendo los parámetros de la acción y los campos de la table. Cuando normalmente llamamos a una acción, suele ser el caso de que la llamada a la acción falle debido a los elementos que faltan en el archivo abi. Por lo tanto, este tutorial analiza el archivo abi y, cuando se produce un error de archivo Abi durante el desarrollo del contrato, también puede identificar la causa del problema. + +El archivo Abi contiene cuatro campos importantes: types、structs、actions、tables. + +![](./png/abi.jpg) + +## types + +El campo types define los alias personalizados para los tipos durante el desarrollo del contrato, por ejemplo: + +```cpp +// El contrato se define como sigue +typedef std::string mystring; +// @abi action +void appyourcom(mystring comname,std::string compub); +... + +// La abi generada se define de la siguiente manera +"types": [{ + "new_type_name": "mystring", + "type": "string" + } +], +``` + +## structs + +El campo structs define el nombre de la table, el tipo de campo que contiene, el nombre de la action y el tipo de parámetros que contiene + +```json +// 以红包合约abi文件为例,structs包含了table的定义和字段、action的定义和字段等详细定义 +"structs": [{ + ....... + { + "name": "record", + "base": "", + "fields": [{ + "name": "packet_issuer", + "type": "uint64" + },{ + "name": "accounts", + "type": "account[]" + } + ] + },{ + "name": "issue", + "base": "", + "fields": [{ + "name": "pubkey", + "type": "string" + },{ + "name": "number", + "type": "uint64" + } + ] + } + ...... +} +``` + +## actions + +El campo de actions--name, type (como name ), payable (tipo bool--si se llama a la action para adjuntar activos--es una de las interfaces externas definidas) + +```json +"actions": [{ + "name": "issue", + "type": "issue", + "payable": true +}, +..... +{ + "name": "close", + "type": "close", + "payable": false +} +], +``` + +## tables + +El campo de table contiene la tabla de varios índices definida, el name (nombre de table, tal como se define en el contrato), index_type (tipo de índice de clave principal, i64), key_names (nombre de miembro de clave principal), key_types (tipo de miembro de clave principal), type (igual que el nombre de la tabla) + + +```json +"tables": [{ + "name": "packet", + "index_type": "i64", + "key_names": [ + "issuer" + ], + "key_types": [ + "uint64" + ], + "type": "packet" + } + ..... +], +``` \ No newline at end of file diff --git a/docs/es/contract/contractfee.md b/docs/es/contract/contractfee.md new file mode 100644 index 0000000..e75ce6f --- /dev/null +++ b/docs/es/contract/contractfee.md @@ -0,0 +1,71 @@ +# Introducción a la tarifa de contrato inteligente + + +En GXChain, hay diferentes cantidades de cargos para implementar, actualizar e invocar contratos. Este documento explica los honorarios asociados con los contratos inteligentes. + + +## La tarifa del contrato de implementación + + +La cuota del contrato de despliegue es pagada por el llamador y se calcula como sigue: +: + +```cpp +// base_fee es 0.01GXC,contract_size es el tamaño del contrato,price_per_kbyte es el costo de 1kb ram,actualmente es 0.2GXC +fee = base_fee + contract_size / 1024 * price_per_kbyte +``` + +## La tarifa de renovación + + +La cuota para la actualización del contrato es pagada por el llamador y se calcula de la siguiente manera: + + +```cpp +// base_fee es 0.01GXC,contract_size es el tamaño del contrato,price_per_kbyte es el costo de 1kb ram,actualmente es 0.2GXC +fee = base_fee + new_contract_size / 1024 * price_per_kbyte +``` + +## Tarifa de contrato de llamada + + +El contrato de llamada es gratuito, pero habrá una tarifa de manejo cuando se llame. La tasa de tramitación consta de tres partes, ram_fee, cpu_fee y base_fee, que se devolverán más tarde. + + +- **ram_fee** + +Cuando se crea o modifica un objeto en la table del contrato, ram_fee puede especificar una cuenta asociada para pagarlo. Ram_fee método de cálculo: + + +```cpp +// ram_bytes为占用的内存字节数,price_per_kbyte_ram为1kb ram的费用,当前为0.2GXC +ram_fee = ram_bytes / 1024 * price_per_kbyte_ram +``` + +| ram_fee payer | Instrucciones | +| --- | --- | +| 0 | Cuenta del contrato (ibid.\_ slef) | +| \_self | Cuenta de contrato (igual que 0)) | +| sender | Cuenta de llamada de contrato | +| original | La cuenta de invocación original del contrato, que se llama a través del contrato, es la cuenta de invocación inicial | + +Ram_fee restitución: después de eliminar el objeto en la table, la tasa incurrida en el momento de la creación será devuelta inmediatamente al payer donde pertenece la memoria. + + +- **cpu_fee** + +El precio unitario actual de cpu_fee es 0 + + +- **base_fee** + +El contrato de llamada, además de usar cpu_fee y ram_fee, tiene una tarifa base de 0.001 GXC. + +Devolución de base_fee: la cuota básica generada por la invocación del contrato será devuelta al saldo no congelado del usuario, que debe ser recogido por el usuario manualmente. +El método de cálculo de invocar una tarifa de contrato inteligente es el siguiente: + +```cpp +// base_fee es 0.001GXC,Ram_fee se calcula en función de la memoria ocupada por el pagador y cpu_fee es 0 +fee = base_fee + ram_fee + cpu_fee +``` + diff --git a/docs/es/contract/debug.md b/docs/es/contract/debug.md new file mode 100644 index 0000000..dc1919a --- /dev/null +++ b/docs/es/contract/debug.md @@ -0,0 +1,78 @@ +# Depuración de contrato + + +En el proceso de desarrollo de contratos inteligentes, la depuración también es muy importante, en la actualidad, la forma de depurar contratos inteligentes, principalmente es utilizar interfaces de cadena de bloque GXChain proporcionadas print para imprimir registros relacionados a la consola witness, por lo que local estructuras, una cadena privada o un inicio local de un nodo de red de prueba sincrónica, es necesario para la depuración del contrato inteligente. + + +Para iniciar la depuración, se requieren dos operaciones: +#### 1. Modifique el archivo config.ini local de la siguiente manera: +``` +[logger.default] +level=debug +appenders=stderr,FILE +``` + +#### 2. Traiga el parámetro `--contracts-console` para el inicio del administrador witness_node + +El modo de depuración print, logra una variedad de tipos de parámetros de sobrecarga. Cadena de soporte, int, punto flotante, hexadecimal, etc. + +::: tip Propina: +Agregue "\n" al registro de impresión, de lo contrario no se imprimirá. +::: + + + +## print + +Diferentes funciones de print se sobrecargan según parámetros diferentes, y las siguientes funciones se llaman internamente, como se muestra en la figura, un tipo diferente de resultado de impresión +![](./png/print.jpg) + +## prints +```cpp +//Imprimir cadena const char* +prints("hello"); +Imprimir: hello +``` + +## prints_l +```cpp +//Imprime los primeros caracteres de una cadena. +prints_l("hello",3); +Imprimir:hel +``` +## printi +```cpp +//Imprime los primeros caracteres de la cadena, el parámetro es de tipo int64_t +printi(-1); +Imprimir:-1 +``` +## printui +```cpp +//Imprima el número sin firmar con el tipo uint64_t como parámetro +printui(-1); +Imprimir:18446744073709551615 +``` + +## printdf +```cpp +//Imprimir el número de punto flotante, el parámetro es doble +printdf(3.14159); +Imprimir:3.141590000000000e+00 +``` + +## printn +```cpp +//Imprima el resultado del cifrado UInt64 tipo base32 +printn(N(hello)); +Imprimir:hello +``` + +## printhex +```cpp +//Imprima en hexadecimal +std::string str="hello"; +checksum256 sum; +sha256(str.c_str(),str.length(),&sum); +printhex(sum.hash,32); +Imprimir:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 +``` diff --git a/docs/es/contract/deploy.md b/docs/es/contract/deploy.md new file mode 100644 index 0000000..5ea7370 --- /dev/null +++ b/docs/es/contract/deploy.md @@ -0,0 +1,135 @@ +# Compilación implementación y invocación del contrato + +## Enfoque IDE de contrato inteligente + +### 1. Cuenta registrada + +Prueba de acceso [monedero en línea](https://testnet.wallet.gxchain.org/#/), registrar cuenta de billetera + +### 2. Reclamar token de prueba + +Se completa el registro, el navegador a `https://testnet.gxchain.org/gxc/get_token?Your_account_name` reclama la moneda de prueba. Reemplace your_account_name por el nombre de la cuenta de red de prueba. + +### 3. Descarga IDE + +Con el IDE de contrato inteligente, puede escribir, compilar, implementar e invocar contratos inteligentes. [Haga clic para descargar](https://github.com/gxchain/gxchain-alpha/releases/latest) + + +### 4. Importar cuenta + + +Vaya a la [billetera en línea](https://testnet.wallet.gxchain.org/#/)) en el paso 1 para encontrar su clave privada para los permisos activos + + +![](../advanced/assets/ide/queryPvk.png) + +![](../advanced/assets/ide/queryPvk2.png) + +Vuelva a abrir el cliente, escriba la página Configuración e importe la cuenta + + +::: warning Nota +La contraseña no se cargará en el servidor. Si lo olvidas, debes quitar la cuenta y volver a importarla +::: + +![](../advanced/assets/ide/import.png) + +### 5. Selección de formulario + +![](../advanced/assets/ide/addProject.png) + +### 6. Compilación + +![](../advanced/assets/ide/compile.png) + +### 7. Implementación + +La billetera debe desbloquearse antes de la implementación + + +![](../advanced/assets/ide/deploy.png) + +![](../advanced/assets/ide/deploy2.png) + +### 8. Invocación + +Al igual que con la implementación, debe desbloquear la billetera primero + +![](../advanced/assets/ide/call.png) + +![](../advanced/assets/ide/call2.png) + +## El modo de línea de comandos local + +### 1. GXChain compilación de código fuente + +Si no desea usar un IDE de contrato inteligente, o desea crear un entorno de compilación más estable y confiable; El programa GXChain puede compilarse localmente, compilarse, implementarse e invocarse mediante el contrato inteligente de la línea de comandos; GXChain compilación de código fuente, actualmente son compatibles con el sistema Ubuntu y el sistema MAC: + +- [Build on Ubuntu](https://github.com/gxchain/gxb-core/wiki/BUILD_UBUNTU) +- [Build on OS X](https://github.com/gxchain/gxb-core/wiki/BUILD_OS_X) + +### 2. Utilice plantillas para crear contratos + +Cree un contrato HelloWorld utilizando la plantilla de GXX + +```bash +gxx -n helloworld +``` + +### 3. Compilar el contrato para generar el wast y abi + +Compile el contrato para generar archivos wast y wasm + +```bash +gxx -o helloworld/helloworld.wast helloworld/helloworld.cpp +``` +Generar un archivo abi + +```bash +gxx -g helloworld/helloworld.abi helloworld/helloworld.cpp +``` + +### 4. Implementación de contrato + +Debe abrir cli_wallet para conectarse a un nodo local o a un nodo testnet remoto + +```bash +./programs/cli_wallet/cli_wallet -swss://testnet.gxchain.org --chain-id c2af30ef9340ff81fd61654295e98a1ff04b23189748f86727d0b26b40bb0ff4 +``` + +Importe la clave privada de la billetera + +```bash +# # Si se trata de una nueva billetera, es necesario establecer una contraseña de desbloqueo, aquí es mylocalpassword + +new >>> set_password mylocalpassword + +# Desbloquear +locked >>> unlock mylocalpassword + +# Importe la clave privada de la billetera +unlocked >>> import_key your_account_name your_private_key + +# El nombre de la cuenta de monedero iniciada es your_accoutn_name. 0 y 0 son vm type y vm version, ./HelloWorld es la ruta de acceso al archivo wast/abi, GXC es el tipo de activo de cuota y true es el broadcast de inicio +unlocked >>> deploy_contract helloworld your_account_name 0 0 ./helloworld GXC true +``` + +### 5. Invocación de contrato +Después de que el contrato de implementación se realiza correctamente, el contrato se puede invocar mediante la interfaz call_contract + + +```bash +unlocked >>> call_contract nathan helloworld null hi "{\"user\":\"zhuliting\"}" GXC true +``` + +### 6. Actualización el contrato + +```bash +unlocked >>> update_contract hello120301 zhao-123 /Users/zhaoxiangfei/code/contracts_work/example_contract_02/helloworld GXC true +``` + + + + + + diff --git a/docs/es/contract/develop.md b/docs/es/contract/develop.md new file mode 100644 index 0000000..46c2fcc --- /dev/null +++ b/docs/es/contract/develop.md @@ -0,0 +1,1206 @@ +# Desarrollo de contratos e introducción de API. + +## Tipo incorporado +Los contratos inteligentes de GXChain, además de todos los tipos compatibles con la sintaxis de C ++, también proporcionan tipos incorporados de contrato. + +### contract\_asset +El tipo de activo en el contrato contiene 2 campos: +```cpp +int64_t amount; +uint64_t asset_id; +``` +Verifique que la cantidad de contract_asset sea válida, use el método de miembro is_amount_within_range +```cpp +bool is_amount_within_range() const { + return -max_amount <= amount && amount <= max_amount; +} +``` + + +::: warning Apunto +En el tipo contract_asset, donde la cantidad representa el número de activos y los grandes números se almacenan en la cadena. Por ejemplo, la precisión de los activos de GXC es 5,1 GXC en realidad debe expresarse como 1 * 100000 = 100000, es decir, la cantidad es de 100000 + +El asset_id representa el ID de instancia del activo (por ejemplo, si el ID de activo es 1.3.1, entonces el último 1 de su ID de instancia). +::: + +Un ejemplo de un tipo de contrato de contract_asset se puede encontrar en el contrato del banco. + +### signature + +Tipo de firma dentro del contrato, definición de la estructura: +```cpp +struct signature { + uint8_t data[65]; +}; +``` + +Example: +```cpp +void verify(checksum256 hash, std::string pub_key, signature sig) +{ + print(pub_key, "\n"); + assert_recover_key(&hash, &sig, pub_key.c_str(), pub_key.length()); +} + ``` + + +### public\_key +El tipo de clave pública en el contrato, la definición de la estructura: +```cpp +struct public_key { + char data[33]; +}; +``` + + +### checksum256 +El tipo de contrato sha256 incorporado, la definición de la estructura: +```cpp +struct ALIGNED(checksum256) { + uint8_t hash[32]; +}; +``` + +Example: +```cpp +void issue(const std::string& question, const checksum256& hashed_answer) +{ + uint64_t owner = get_trx_sender(); + records.emplace(owner, [&](auto &p) { + p.issuer = owner; + p.question = question; + p.hashed_answer = hashed_answer; + }); +} +``` + + +### checksum160 +El tipo ripemd160 incorporado del contrato, la definición de la estructura: +```cpp +struct ALIGNED(checksum160) { + uint8_t hash[20]; +}; +``` + +### checksum512 +Tipo Sha512 dentro del contrato, definición de la estructura: +```cpp +struct ALIGNED(checksum512) { + uint8_t hash[64]; +}; +``` + +### block\_id\_type +El tipo block_id_type incorporado del contrato, la definición de la estructura: +```cpp +typedef struct checksum160 block_id_type; +``` +## API incorporada + + +Desarrolle contratos inteligentes en GXChain, puede llamar a la API integrada para lograr características más completas + +| belong | api name | description | +| --- | --- | --- | +| | current_receiver | Devuelve el ID de instancia de la cuenta de contrato actual (es decir, el último dígito del ID de cuenta) | +| | get_action_asset_id | Devuelve el ID de instancia de activo enviado por esta llamada al contrato (es decir, el último dígito del ID de activo)| +| | get_action_asset_amount | Devuelve el número de activos enviados al contrato por esta llamada. | +| | withdraw_asset | Transfiera los activos de la cuenta del contrato actual a la cuenta de la cadena | +| | get_balance | Obtenga el saldo de un activo en la cuenta en la cadena | +| | sha1 | Calcula el sha1 de los datos. | +| | sha256 | Cálculo del sha256 de los datos. | +| | sha512 | Cálculo del sha512 de los datos. | +| | ripemd160 | Calcular los datos de ripem160. | +| | assert_recover_key | Verifique que la firma y el hash dados puedan recuperar la clave pública | +| | get_head_block_num | Obtener el último número de bloque | +| | get_head_block_id | Consigue el último hash de bloque | +| | get_block_id_for_num | Obtener el hash de bloque especificado | +| | get_head_block_time | Obtenga el tiempo del último bloque, devuelva el valor en segundos | +| | get_trx_sender | Obtenga el instance_id de la cuenta que llamó al contrato | +| | get_account_id | Obtenga el instance_id de la cuenta que llamó al contrato | +| | get_account_name_by_id | Obtenga un nombre de cuenta basado en el ID de instancia de cuenta | +| | get_asset_id | Obtenga el instance_id del activo basado en el nombre del activo | +| | read_transaction | Lea la transacción actual de datos serializados. | +| | transaction_size | La longitud de los datos después de la transacción actual se serializa | +| | expiration | Obtener tiempo de expiración de la transacción | +| | tapos_block_num | Devuelve el número de bloque al que hace referencia la transacción. | +| | tapos_block_prefix | Devuelve el ID de bloque de la referencia de transacción (los segundos 32 dígitos) | +| | read_action_data | Leer datos de acción actuales | +| | action_data_size | Devuelve el número de bytes necesarios para leer los datos de acción actuales | +| | send_inline | Acción de llamada en línea | +| | unpack_action_data | Deserializar los datos de acción actuales en un objeto de acción definido | +| | graphene_assert | Si no se cumple la condición, interrumpa la ejecución de este contrato y renueve todos los estados | +| | graphene_assert_message | Si no se cumple la condición, interrumpa la ejecución de este contrato y renueve todos los estados | +| | print | Imprimir para el registro al depurar | + + + +### current\_receiver + +**Tipo de función:** `uint64_t current_receiver()` + +**Archivo de encabezado:** `` + +**Descripción de la función:** devuelve el ID de instancia de la cuenta de contrato actual (es decir, el último dígito del ID de cuenta) + +**Valor de retorno:** devuelve el ID de instancia de la cuenta de contrato actual. + +**Ejemplo:** + +```cpp +// @abi action +void examcurr(){ + uint64_t ins_id = current_receiver(); + print("current contract account id: ", ins_id, "\n"); +} +``` + +**Tipo de función:** `uint64_t get_action_asset_id ()` +**Archivo de encabezado:** `` +**Descripción funcional:** devuelve el ID de instancia de activo (es decir, el último dígito del ID de activo) enviado al contrato por esta llamada. +**Valor de retorno:** el retorno 0 significa que la acción no tiene activos adjuntos, el retorno no cero significa el id de instancia del activo +**Ejemplo:** + + +```cpp +// @abi action +void examgetast(){ + uint64_t ast_id = get_action_asset_id(); + print("call action asset id: ",ast_id,"\n"); +} +``` + +### get\_action\_asset\_amount + +**Tipo de función:** `uint64_t get_action_asset_id ()` +**Archivo de encabezado:** `` +**Descripción funcional:** devuelve el ID de instancia de activo (es decir, el último dígito del ID de activo) enviado al contrato por esta llamada. +**Valor de retorno:** el retorno 0 significa que la acción no tiene activos adjuntos, el retorno no cero significa el id de instancia del activo +**Ejemplo:** + + +```cpp +//get_action_asset_amount +// @abi action +void examgetamo(){ + int64_t amount = get_action_asset_amount(); + print("call action asset amount: ",amount,"\n"); +} +``` + + +### withdraw\_asset + +**Tipo de función:** `void retirada_asset (uint64_t from, uint64_t to, uint64_t asset_id, int64_t cantidad)` +**Archivo de encabezado:** `` +**Descripción funcional:** transfiera los activos del contrato actual a una cuenta externa +**Parámetros:** + + + +Parámetro | Tipo | Descripción +---|---|--- +from | uint64_t | +to | uint64_t | +asset_id | uint64_t | +amount | int64_t | + +**Ejemplo::** + +```cpp +// @abi action +void examwith(uint64_t from,uint64_t to, uint64_t asset_id, int64_t amount){ + withdraw_asset(from,to,asset_id,amount); + print("withdraw_asset example\n"); +} +``` + + +### get\_balance + +**Tipo de función:** `int64_t get_balance (cuenta int64_t, int64_t asset_id)` +**Archivo de encabezado:** `` +**Descripción funcional:** Obtenga un saldo de activos en la cuenta en la cadena +**Valor de retorno:** devuelve el saldo de un activo en la cuenta en la cadena +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +account | int64_t | Cuanta en cadena instace_id +asset_id | int64_t | Activo designadnstance_id + +**Ejemplo:** + +```cpp +// @abi action +void examgetbl(int64_t account, int64_t asset_id){ + int64_t balance = get_balance(account, asset_id); + print("account balance: ",balance,"\n"); +} +``` + +### sha1 + +**El tipo de función del activo especificado:** `void sha1 (const char * data, uint32_t length, checksum160 * hash)` +**Archivo de encabezado:** `` +**Descripción funcional:** Sha1 para el cálculo de datos. +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +data | const char* | La primera dirección de la cadena utilizada para calcular sha1 +length | uint32_t | Longitud de la cadena de datos +hash | checksum160* | Participa en el sha1 para almacenar cálculos. + +**Ejemplo:** + +```cpp +// @abi action +void examsha1(std::string data){ + checksum160 hash; + sha1(data.c_str(),data.length(),&hash); + printhex(hash.hash,20); + print("\n"); +} +``` + +### sha256 + +**Tipo de función:** `void sha256 (const char * data, uint32_t length, checksum256 * hash)` +**Archivo de encabezado:** `` +**Descripción funcional:** sha256 para el cálculo de datos. +**Parámetros:** + + +Parámetro | Tipo | Descripción +---|---|--- +data | const char* | La primera dirección de la cadena utilizada para calcular sha256 +length | uint32_t | Longitud de la cadena de datos +hash | checksum256* | Participa en el sha256 para almacenar cálculos. + +**Ejemplo:** + +```cpp +// @abi action +void examsha25(std::string data){ + checksum256 hash; + sha256(data.c_str(),data.length(),&hash); + printhex(hash.hash,32); + print("\n"); +} +``` + + +### sha512 + +**Tipo de función:** `void sha512 (const char * data, uint32_t length, checksum512 * hash)` +**Archivo de encabezado:** `` +**Descripción funcional:** sha512 para el cálculo de datos. +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +data | const char* | La primera dirección de la cadena utilizada para calcular sha512 +length | uint32_t | Longitud de la cadena de datos +hash | checksum512* | Participa en el sha512 para almacenar cálculos. + +**Ejemplo:** + +```cpp +// @abi action +void examsha512(std::string data){ + checksum512 hash; + sha512(data.c_str(),data.length(),&hash); + printhex(hash.hash,64); + print("\n"); +} +``` + + +### ripemd160 + +**Tipo de función:** `void ripemd160 (const char * data, uint32_t length, checksum160 * hash)` +**Archivo de encabezado:** `` +**Descripción funcional:** calcular datos para ripem160 +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +data | const char* | La primera dirección de la cadena utilizada para calcular ripem160 +length | uint32_t | Longitud de la cadena de datos +hash | checksum160* | Consulte el findemd160 para almacenar cálculos + +**Ejemplo:** + +```cpp +// @abi action +void examripemd(std::string data){ + checksum160 hash; + ripemd160(data.c_str(),data.length(),&hash); + printhex(hash.hash,20); + print("\n"); +} +``` + +### assert\_recover\_key + +**Tipo de función:** `void assert_recover_key (const checksum256 * digest, const signature * sig, const char * pub, uint32_t publen);` +**Archivo de encabezado:** `` +**Descripción funcional:** verifique que la firma y el hash dados puedan recuperar la clave pública +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +data | const checksum256* | Valor de hash Sha256 +sig | const signature* | Los datos después de firmar la cadena original. +pub | const char* | Clave pública ([formato hexadecimal: ver gxbjs / src / ecc / PublicKey.js](https://github.com/gxchain/gxbjs/blob/master/lib/ecc/src/PublicKey.js#L161)) +publen | uint32_t | Lontitud de clave pública + +**Ejemplo:** + +```cpp +// @abi action +void examrecover(checksum256 hash,signature sig,std::string pkey) +{ + assert_recover_key(&hash, &sig, pkey.c_str(), pkey.length()); +} +``` + +### get\_head\_block\_num + +**Tipo de función:** `int64_t get_head_block_num ()` +**Archivo de encabezado:** `` +**Descripción funcional:** Volver al último número de bloque +**Valor de retorno:** devuelve el último número de bloque +**Ejemplo:** + +```cpp +// @abi action +void examgetnum(){ + int64_t head_num = get_head_block_num(); + print("head block num: ",head_num, "\n"); +} +``` + +### get\_head\_block\_id + +**Tipo de función:** void get_head_block_id (checksum160 * hash) +**Archivo de encabezado:** +**Descripción funcional:** obtén el último hash de bloque +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +hash | checksum160* | Obtener el valor hash del último bloque + +**Ejemplo:** + +```cpp +// @abi action +void examgetid(){ + checksum160 block_hash; + get_head_block_id(&block_hash); + printhex(block_hash.hash,20); + print("\n"); +} +``` + + +### get\_block\_id\_for\_num + +**Tipo de función:** `void get_block_id_for_num(checksum160* hash, uint32_t block_num)` + +**Archivo de encabezado:**`` + +**Descripción funcional:** obtener el hash de bloque especificado + +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +hash | checksum160* | Obtener el valor hash del bloque especificado +block_num | uint32_t | Número de bloque especificado + +**Ejemplo:** + +```cpp +// @abi action +void examidnum(){ + checksum160 block_hash; + get_block_id_for_num(&block_hash,1); //get the hash of first block + printhex(block_hash.hash,20); + print("\n"); +} +``` + + +### get\_head\_block\_time + +**Tipo de función:** `int64_t get_head_block_time()` + +**Archivo de encabezado:**`` + +**Descripción funcional:** tiempo para obtener el último bloque, devolver el valor en segundos + +**Valor de retorno:** devuelve el último tiempo de bloqueo + +**Ejemplo:** + +```cpp +// @abi action +void examgettime(){ + int64_t head_time; + head_time = get_head_block_time(); + print("head block time: ",head_time,"\n"); +} +``` + + +### get\_trx\_sender + +**Tipo de función:** `uint64_t get_trx_sender()` + +**Archivo de encabezado:**`` + +**Descripción funcional:** + +**Valor de retorno:** + +**Ejemplo:** + +```cpp +// @abi action +void examgettrx(){ + uint64_t sender_id; + sender_id = get_trx_sender(); + print("call action instance id: ",sender_id,"\n"); +} +``` + + +### get\_account\_id + +**Tipo de función:** `int64_t get_account_id(const char * data, uint32_t length)` + +**Archivo de encabezado:**`` + +**Descripción funcional:** obtener el instance_id de la cuenta de acuerdo con el nombre de la cuenta + +**Valor de retorno:** el retorno -1 significa que no hay nombre de cuenta, el valor de retorno> = 0 significa el id de instancia de la cuenta + +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +data | const char* | Nombre de cuenta, por ejemplo nathan +length | uint32_t | Lontitud de cuenta nombre,Por ejemplo la lontitud de nathan es 6 + +Devuelve el instance_id de la cuenta si la cuenta existe, o -1 si la cuenta no existe + +**Ejemplo:** + +```cpp +// @abi action +void examgetacid(std::string data){ + int64_t acc_id; + acc_id = get_account_id(data.c_str(), data.length()); + print("account id: ",acc_id,"\n"); +} +``` + +### get\_account\_name\_by\_id + +**Tipo de función:** `int64_t get_account_name_by_id(array_ptr data, size_t buffer_size, int64_t account_id)` + +**Archivo de encabezado:**`` + +**Descripción funcional:** obtener el nombre de la cuenta de acuerdo con la identificación de la instancia de la cuenta + +**Valor de retorno:** Devolver -1 significa que no hay cuenta, valor de retorno 0 significa obtener el nombre de la cuenta correctamente. + + +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +data | const char* | Nombre de cuenta, por ejemplo nathan +length | uint32_t | Lontitud de cuenta nombre,Por ejemplo la lontitud de nathan es 6 +account_id | int64_t | instance id o id de instance account + +Devuelve 0 si la cuenta existe, o -1 si la cuenta no existe + + +**Ejemplo:** + +```cpp +// @abi action +void examgetname(int64_t accid){ + char data[65]={0}; + int64_t result; + result = get_account_name_by_id(data,65,accid); + print(static_castdata,"\n"); +} +``` + +### get\_asset\_id + +**Tipo de función:** `int64_t get_asset_id(const char * data, uint32_t length)` + +**Archivo de encabezado:**`` + +**Descripción funcional:** obtenga el instance_id del activo basado en el nombre del activo + +**Valor de retorno:** retorno -1 significa que no hay tal nombre de activo, valor de retorno> = 0 significa el id de instancia del activo + +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +data | const char* | Nombre del activo +length | uint32_t | La longitud del nombre del activo, como la longitud de GXC es 3 + +**Ejemplo:** + +```cpp +// @abi action +void examassid(std::string data){ + int64_t assid; + assid = get_asset_id(data.c_str(),data.length()); + print("asset id: ",assid,"\n"); +} +``` + +### read\_transaction + +**Tipo de función:** `int read_transaction(char* dst, uint32_t dst_size)` + +**Archivo de encabezado:**`` + +**Descripción funcional:** leer los datos serializados de la transacción actual a dst + +**Valor de retorno:** cuando dst_size es 0, devuelve el número de bytes necesarios para la lectura; cuando dst_size no es 0, devuelve el número de bytes realmente leídos (el valor mínimo de dst_size y el tamaño de transacción) + + + +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +dst | char* | Puntero para recibir el buffer de datos de lectura. +dst_size | uint32_t | Longitud para leer + +**Ejemplo:** + +```cpp +// @abi action +void examreadtrx(){ + int dwsize; + dwsize =transaction_size(); + char* pBuffer = new char[dwsize]; + uint32_t size = read_transaction(pBuffer,dwsize); + delete[] pBuffer; +} +``` + +### transaction\_size + +**Tipo de función:** `int transaction_size()` + +**Archivo de encabezado:**`` + +**Descripción funcional:** obtener la longitud de los datos después de la serialización de la transacción actual + +**Valor de retorno:** devuelve la longitud de los datos serializados + +**Ejemplo:** + +```cpp +// @abi action +void examtrxsize(){ + int dwsize; + dwsize =transaction_size(); + print("the size of the serialize trx: ",dwsize,"\n"); +} +``` + +### expiration + +**Tipo de función:** `uint64_t expiration()` + +**Archivo de encabezado:**`` + +**Descripción funcional:** obtener tiempo de expiración de la transacción + +**Valor de retorno:** Tiempo de vencimiento de la transacción de retorno + +**Ejemplo:** + +```cpp +// @abi action +void exampira(){ + uint64_t timenum = expiration(); + print("the expiration time: ", timenum,"\n"); +} +``` + + +### tapos\_block\_num + +**Tipo de función:** `int tapos_block_num()` + +**Archivo de encabezado:**`` + +**Descripción funcional:** obtener el número de bloque de la referencia de transacción + +**Valor de retorno:** devuelve el número de bloque de la referencia de transacción + +**Ejemplo:** + +```cpp +// @abi action +void examtapnum(){ + uint64_t tapos_num; + tapos_num = tapos_block_num(); + print("ref block num: ",tapos_num,"\n"); +} +``` + + +### tapos\_block\_prefix + +**Tipo de función:** `uint64_t tapos_block_prefix()` + +**Archivo de encabezado:**`` + +**Descripción funcional:** Obtenga el ID de bloque de la referencia de transacción (los segundos 32 dígitos) + +**Valor de retorno:** devuelve el ID de bloque de la referencia de transacción (los segundos 32 dígitos) + +**Ejemplo:** + +```cpp +// @abi action +void examtappre(){ + uint64_t tapos_prefix; + tapos_prefix = tapos_block_prefix(); + print("ref block id: ",tapos_prefix,"\n"); +} +``` + + +### read\_action\_data + +**Tipo de función:** `uint32_t read_action_data( void* msg, uint32_t len )` + +**Archivo de encabezado:**`` + +**Descripción funcional:** leer los datos de acción actuales + +**Valor de retorno:** devuelve el número de bytes realmente leídos. Si len es 0, se devuelve el número de bytes necesarios para la lectura. + +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +msg | void* | Puntero de buffer de recepción +len | uint32_t | Longitud de lectura + +**Ejemplo:** + +```cpp +// @abi action +void examract(uint64_t num,std::string number){ + auto size = action_data_size(); + char *buffer = static_cast(malloc(size)); + read_action_data((void*)buffer,size); + printhex(buffer,size); + print("\n"); +} +``` + +### action\_data\_size + +**Tipo de función:** `uint32_t action_data_size()` + +**Archivo de encabezado:**`` + +**Descripción funcional:** el número de bytes necesarios para leer los datos de acción actuales + +**Valor de retorno:** devuelve el número de bytes necesarios para la lectura + +**Ejemplo:** + +```cpp +// @abi action +void examrasize(uint64_t num,std::string number){ + auto size = action_data_size(); + print("size: ", size,"\n"); +} +``` + +### send\_inline + +**Tipo de función:** `void send_inline(char *serialized_action, size_t size)` + +**Archivo de encabezado:**`` + +**Descripción funcional:** acción de ejecución en línea (generalmente mediante la construcción de una acción y la ejecución indirecta de la acción a través de su método de miembro de envío, su implementación interna es send_inline, llamada de contrato cruzado) + +### unpack\_action\_data + +**Tipo de función:** `T unpack_action_data()` + +**Archivo de encabezado:**`` + +**Descripción funcional:** desempaquetar datos de acción actuales + +**Valor de retorno:** devuelve la estructura de acción después de desempaquetar + +**Ejemplo:** + +```cpp +struct myaction { + uint64_t num; + std::string name; + + GRAPHENE_SERIALIZE(myaction,(num)(name)) +}; +// @abi action +void examupact(uint64_t num,std::string name){ + auto my = unpack_action_data(); + print(my.name,"\n"); +} +``` + +### graphene\_assert + +**Tipo de función:** `void graphene_assert(uint32_t test, const char* msg)` + +**Archivo de encabezado:**`` + +**Descripción funcional:** Si no se cumple la condición, interrumpa la ejecución de este contrato y renueve todos los estados + + +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +test | uint32_t | Condición de verificación +msg | const char* | Deshacer el mensaje de salida si no se cumple la condición + + +**Ejemplo:** + +```cpp +// @abi action +void examassert(){ + uint64_t number=1; + graphene_assert(number == 1, "wrong!"); +} +``` + + +### graphene\_assert\_message + +**Tipo de función:** `void graphene_assert_message(uint32_t test, const char* msg, uint32_t msg_len)` + +**Archivo de encabezado:**`` + +**Descripción funcional:** Si no se cumple la condición, interrumpa la ejecución de este contrato y renueve todos los estados + + + +**Parámetros:** + +Parámetro | Tipo | Descripción +---|---|--- +test | uint32_t | Condición de verificación +msg | const char* | Deshacer el mensaje de salida si no se cumple la condición +msg_len | uint32_t | Lontitud de contento de mensaje + +**Ejemplo:** + +```cpp +// @abi action +void examassmsg(){ + uint64_t number=1; + std::string msg = "wrong!!!"; + graphene_assert_message(number == 1, msg.c_str(),msg.length()); +} +``` + + +### print + +**Tipo de función:** `void print(const char* ptr)` + +**Archivo de encabezado:**`` + +**Descripción funcional:** imprimir para registro cuando se realiza la depuración (para un uso detallado, verifique la depuración del contrato) + + +**Parámetros:** +Parámetro | Tipo | Descripción +---|---|--- +ptr | const char* | Contenido del cuerpo del mensaje depurado + +**Ejemplo:** + +```cpp +// @abi action +void examprint(){ + print("example example example!!!\n"); +} +``` + +### Ejemplo + +El contrato de muestra para el uso de api se ha implementado en la red de prueba, que puede ser probada por el cliente IDE, [haga clic para ver la fuente del contrato](./question.html), `apitest` de la cuenta del contrato + +![](./png/apitest.jpg) + +## Llamada a través del contrato + + +### instrucciones +GXChain admite llamadas entre contratos y es compatible con cuentas de pago que establecen tarifas de ram. Ejemplos de llamadas de contrato cruzado son Usuario -> contrato_A -> contrato_B. Para contrato contrato_B, el Usuario es el llamador original y el contrato_A es remitente. +Límite de nivel de llamada entre contratos: no más de tres contratos en la cadena de llamadas. Es decir: Usuario -> contrato_A -> contrato_B -> contrato_C, si se excede el número de capas, se terminará la ejecución. (Si la cadena de llamadas forma una llamada en bucle, también terminará la ejecución) +El recurso RAM utilizado en el contrato, la cuenta de pago se puede establecer en las siguientes cuatro identidades: + +| ram_fee payer | instrucción | +| --- | --- | +| 0 | Cuenta de contrato en sí (igual que \_slef) | +| \_self | Cuenta de contrato en sí (igual que 0) | +| sender | Contrato de cuenta de llamada | +| original | La cuenta de llamada original del contrato, llamada de contrato cruzado, llame a la cuenta para el inicio | + + +### Ejemplo +`contract_A` -> `contract_B`, `contract_A` contract llama a `contract_B` contract. +1. Construya la acción en `contract_A`, incluyendo el ID de cuenta / nombre de cuenta `contract_B`, nombre de acción, parámetro, cuenta de llamada (\_self), activos adicionales +2. Llame al método de envío de la acción para completar la llamada de contrato cruzado. + +```cpp + +#contract_b Contrato +··· +void hi(std::string name,uint64_t number) +{ + ··· +} +··· +#contract_A contrato +··· +struct param { + std::string name; + uint64_t number; +}; + + +void inlinecall(uint64_t con_b_id, std::string con_b_name){ + + param par{"hello", 100}; + + // Método 1:Al construir una acción, utilice el ID de cuenta del contrato + action contract_b_id(con_b_id, N(hi), std::move(par), _self, {1000, 1}); + contract_b_id.send(); + + // Método 2: al construir una acción, use el nombre de la cuenta del contrato + action contract_b_name(con_b_name, N(hi), std::move(par), _self, {1000,1}); + contract_b_name.send(); +} +··· +``` + + +## Tabla de índice múltiple + +#### index +* [Perfil de almacenamiento de contrato](#smart_contract_storage_brief_introduction) +* [El código de ejemplo](#example) +* [Defina el tipo de almacenamiento](#define_type) +* [Aumentar](#add) +* [Eliminar](#delete) +* [Comprobar](#find) +* [cambiar](#modify) + + +### Perfil de almacenamiento de contrato + +Se utiliza para conservar los datos del contrato de almacenamiento. +Los datos deben almacenarse en unidades de instancias de la clase C ++, por lo que las clases C ++ almacenadas deben definirse en el contrato. Cada clase tiene una tabla, similar a una sola tabla en una base de datos relacional. La diferencia es que tiene las siguientes características: +>Soporte para multiples índices. +>La indexación conjunta no es compatible +>Sólo la clave principal es única. +>El tipo de índice solo admite el tipo uint64_t +>Si desea usar una cadena como un índice, debe usar uint64_t string_to_name (string str) en la biblioteca del contrato para convertir la cadena a uint64_t. La longitud de la cadena está limitada a 12 caracteres y solo puede incluir ([az]. [1-5 ]) Un total de 32 caracteres. +>Para índices distintos de la clave principal, cuando hay varios valores de índice de registro, el objeto adquirido es el registro insertado más antiguo. +>Soporte para adiciones y eliminaciones. + +El siguiente contenido es alrededor del ejemplo para ilustrar + +[go_back](#index) + + +### Código de muestra + +```cpp +#include +#include +#include +#include + +using namespace graphene; + +class multindex : public contract +{ + struct offer; + + public: + multindex(uint64_t id) + : contract(id) + , offers(_self, _self) + { + } + + //@abi action + void additem(uint64_t i1, uint64_t i2, std::string name) + { + uint64_t pk = offers.available_primary_key(); + print("pk=", pk); + offers.emplace(0, [&](auto &o) { + o.id = pk; + o.idx1 = i1; + o.idx2 = i2; + o.stringidx = graphenelib::string_to_name(name.c_str()); + }); + } + + //@abi action + void getbypk(uint64_t key) + { + auto it = offers.find(key); + if (it != offers.end()) { + dump_item(*it); + } + } + + //@abi action + void getbyidx1(uint64_t key) + { + auto idx = offers.template get_index(); + auto matched_offer_itr = idx.lower_bound(key); + if (matched_offer_itr != idx.end()) { + dump_item(*matched_offer_itr); + } + } + + //@abi action + void getbyidx2(uint64_t key) + { + auto idx = offers.template get_index(); + auto matched_offer_itr = idx.lower_bound(key); + if (matched_offer_itr != idx.end()) { + dump_item(*matched_offer_itr); + } + } + + //@abi action + void getbystring(std::string key) + { + auto idx = offers.template get_index(); + auto matched_offer_itr = idx.lower_bound(N(key)); + if (matched_offer_itr != idx.end()) { + dump_item(*matched_offer_itr); + } + } + + private: + void dump_item(const offer &o) + { + print("offer.id:", o.id, "\n"); + print("offer.idx1:", o.idx1, "\n"); + print("offer.idx2:", o.idx2, "\n"); + graphenelib::name n; + n.value = o.stringidx; + print("offer.stringidx:", n.to_string().c_str(), "\n"); + } + + private: + //@abi table offer i64 + struct offer { + uint64_t id; + uint64_t idx1; + uint64_t idx2; + uint64_t stringidx; + + uint64_t primary_key() const { return id; } + + uint64_t by_index1() const { return idx1; } + + uint64_t by_index2() const { return idx2; } + + uint64_t by_stringidx() const {return stringidx; } + + GRAPHENE_SERIALIZE(offer, (id)(idx1)(idx2)(stringidx)) + }; + + typedef multi_index>, + indexed_by>, + indexed_by>> + offer_index; + + offer_index offers; +}; + +GRAPHENE_ABI(multindex, (additem)(getbypk)(getbyidx1)(getbyidx2)(getbystring)) + +``` + + +### Definir el tipo de almacenamiento + +```cpp +private: + //@abi table offer i64 + struct offer { + uint64_t id; + uint64_t idx1; + uint64_t idx2; + uint64_t stringidx; + + uint64_t primary_key() const { return id; } + + uint64_t by_index1() const { return idx1; } + + uint64_t by_index2() const { return idx2; } + + uint64_t by_stringidx() const {return stringidx; } + + GRAPHENE_SERIALIZE(offer, (id)(idx1)(idx2)(stringidx)) + }; + + typedef multi_index>, + indexed_by>, + indexed_by>> offer_index; + offer_index offers; +``` + +El tipo debe estar anotado // @ abi table offer i64 +@abi tabla de escritura fija +La oferta es un nombre de tabla, que se puede personalizar de acuerdo con los requisitos del negocio y no puede exceder los 12 caracteres y solo puede ser [a-z] [1-5]. Un total de 32 caracteres, comenzando con letras y. +I64 es el tipo de índice, puede escribir i64 + + +Para struct offer {...} es una clase c ++ normal, la parte inferior GRAPHENE_SERIALIZE (offer, (id) (idx1) (idx2) (stringidx) se usa para la serialización +GRAPHEN_SERIALIZE (nombre del tipo, (nombre del campo 1) (nombre del campo 2) (nombre del campo 3) (nombre del campo 4) ...) + + +Uint64_t primary_key () const {return id;} El nombre de la función y el tipo de este código son fijos, no se pueden cambiar, se usan para especificar una clave primaria única, aquí id como la clave primaria + + +Las otras 3 funciones se utilizan para definir el índice secundario. + +El siguiente código se usa para definir un índice basado en una clase de c ++ definida: +```cpp +typedef multi_index>, + indexed_by>, + indexed_by>> offer_index; + +typedef multi_index>, + const_mem_fun + +// Este código define un índice secundario. Una tabla puede definir hasta 16 índices secundarios +//N (idx1) se utiliza para definir el nombre del índice +// El primer parámetro de los corchetes angulares es el nombre del tipo de oferta definido anteriormente, el segundo parámetro es el tipo del índice y el tercer parámetro es el nombre de la función en la clase de oferta llamada por el índice + +``` + +Finalmente, debe definir la instancia de índice del índice en las ofertas de contract_index del contrato, en el constructor del contrato necesita usar el contrato _self (ID del contrato) para inicializar: +```cpp + multindex(uint64_t id) + : contract(id) + , offers(_self, _self) + {} +``` +[go_back](#index) + + +#### Aumentar +```cpp +uint64_t pk = offers.available_primary_key(); +print("pk=", pk); +offers.emplace(0, [&](auto &o) { + o.id = pk; + o.idx1 = i1; + o.idx2 = i2; + o.stringidx = graphenelib::string_to_name(name.c_str()); +}); +``` +`uint64_t pk = offers.available_primary_key ()` se usa para obtener la siguiente clave primaria válida de la clave primaria autoincrementante, o puede especificarla usted mismo + + +```cpp +offers.emplace(0, [&](auto &o) { + o.id = pk; + o.idx1 = i1; + o.idx2 = i2; + o.stringidx = graphenelib::string_to_name(name.c_str()); +}); +``` + +Insertar un objeto con una expresión lambda para asignar un valor al objeto recién agregado o + +`o.stringidx = graphenelib::string_to_name(name.c_str())`Esta es la implementación del tipo de cadena como un índice. No se admite el uso directo de una cadena como un índice. + +[go_back](#index) + + +#### 删 + +Por favor lea [primero](#find) +La eliminación generalmente se elimina a través del iterador de la tabla, generalmente llama a encontrar para encontrar el iterador del objeto que se eliminará para eliminar +`offers.erase (it)` es un iterador para encontrar el objeto devuelto + +[go_back](#index) + + +#### Cancelar +```cpp +auto idx = offers.template get_index(); +auto matched_offer_itr = idx.lower_bound(N(key)); +if (matched_offer_itr != idx.end()) { + dump_item(*matched_offer_itr); +} +``` + + + +`auto idx = offers.template get_index ()` Obtenga el índice del nombre de la tabla de ofertas `stringidx`, la tabla de ofertas tiene 4 índices, uno es el índice de clave principal y los otros tres niveles son `idx1`, `idx2`, `stringidx`, clave principal La búsqueda del índice es más conveniente. No es necesario obtener el índice por el nombre del índice y, a continuación, buscar la key correspondiente según el índice, pero se ofrece `offers.find (pk)`, que también es un iterador del objeto devuelto. +`auto matched_offer_itr = idx.lower_bound(N(key))` encuentra el objeto de clave principal correspondiente a la clave de cadena por índice y devuelve el iterador correspondiente `matched_offer_itr` + +[go_back](#index) + + +#### cambiar + +Por favor lea [primero](#find) + +La modificación de un objeto generalmente se modifica mediante el iterador del objeto y la expresión lambda. + +```cpp +offers.modify(it, 0, [&](auto &o) { + // + o.idx1 = 1000; +}); +``` +[go_back](#index) diff --git a/docs/es/contract/error_collection.md b/docs/es/contract/error_collection.md new file mode 100644 index 0000000..6a33f4c --- /dev/null +++ b/docs/es/contract/error_collection.md @@ -0,0 +1,93 @@ +# Errores comunes de desarrollo + +Hay muchos tipos de errores que pueden ocurrir durante el desarrollo, por lo que este tutorial cubrirá muchos de ellos a lo largo del tiempo (incluyendo el desarrollo de contratos comunes y los problemas relacionados con el desarrollo de C++). + +## 1. Error en el archivo de encabezado VsCode + +Motivo del error: dado que la compilación de origen ha fallado, el archivo de encabezado dependiente del contrato no se agregó a la variable de entorno. + +Solución: puede establecla manualmente en el software vscode y editar el directorio . vscode--> c_cpp_properties. json + +```json +"includePath": [ + "${workspaceFolder}/**", + "/Users/zhaoxiangfei/code/gxb-core/contracts", //Reemplace con su propia ruta de archivo de encabezado de contrato + "/Users/zhaoxiangfei/code/gxb-core/externals/magic_get/include" //Reemplaza con tu propio camino. +], +``` + +## 2. El archivo abi generado carece de entradas + +Motivo del error: no se agregó ningún comentario a la acción o tabla para las llamadas externas, lo que posiblemente resultaría en la falta de archivos abi analizados por la herramienta gxx. + +Solución: agregue comentarios a la acción y la tabla, como se muestra a continuación: +```cpp +// Invoque la acción sin recursos adicionales +// @abi action +void hi(std::string user){ + ... +} + +// Invoque la acción con recursos adicionales +// @abi action +// @abi payable +void issue(std::string pubkey, uint64_t number){ + ... +} + +// La tabla de índice múltiple +//@abi table packet i64 +struct packet { + ... +}; + +``` + +## 3. Error al operar tabla de índice múltiple (agregar, cambiar) + +Motivo del error: es posible que el argumento de la expresión lambda pasada no sea una referencia al objeto, sino que solo se modifique una copia del objeto. + +Solución: cambie el argumento a la expresión lambda por una referencia al objeto. + +```cpp +offers.emplace(0, [&](auto &o) { + o.id = offers.available_primary_key();; + ... +}); +``` +## 4. Se ha producido un error al llamar a una acción en el contrato + +Motivo de error: además de la causa lógica de la acción en sí, todavía es necesario comprobar si hay errores en el archivo abi y los errores en el GRAPHENE_ABI + +Solución: Compruebe si la acción existe en la abi y si la macro GRAPHENE_ABI contiene la acción + +```cpp +// Si no se incluye una acción, el contrato todavía se puede implementar correctamente, salvo que no puede controlar la acción invocada cuando se invoca +GRAPHENE_ABI(hello,(hi)) +``` + +## 5. Compilado usando la herramienta gxx, "no se encontraron archivos de cabecera" + +Motivo de error: como en el problema 1, el archivo de encabezado no se copió en el directorio del sistema porque la compilación del código fuente falló o la realización de `sudo make install` no tuvo éxito. +Solución: compile correctamente el código, tutorial de compilación de código fuente haga [clic aquí](https://github.com/gxchain/gxb-core), si hay problemas en la compilación del código fuente, envíe los problemas en la página de github del código fuente. + + +## 6. El contrato de actualización provocó un error de serialización de tabla + +Motivo de error: el contrato de actualización elimina o modifica los campos de la tabla, lo que genera un error de serialización + +Solución: actualizar el contrato para no modificar la tabla original, agregar nueva tabla necesita para asegurarse de que el orden de campo y el orden de serialización. +```cpp +struct packet { + uint64_t issuer; + std::string pub_key; + contract_asset total_amount; + uint32_t number; + vector subpackets; + + uint64_t primary_key() const { return issuer; } + + //El orden de serialización debe ser coherente con el orden de definición de campo + GRAPHENE_SERIALIZE(packet, (issuer)(pub_key)(total_amount)(number)(subpackets)) +}; +``` diff --git a/docs/es/contract/png/abi.jpg b/docs/es/contract/png/abi.jpg new file mode 100644 index 0000000..bcbcfcd Binary files /dev/null and b/docs/es/contract/png/abi.jpg differ diff --git a/docs/es/contract/png/apitest.jpg b/docs/es/contract/png/apitest.jpg new file mode 100644 index 0000000..8dfb800 Binary files /dev/null and b/docs/es/contract/png/apitest.jpg differ diff --git a/docs/es/contract/png/chain_id.jpg b/docs/es/contract/png/chain_id.jpg new file mode 100644 index 0000000..8c9436a Binary files /dev/null and b/docs/es/contract/png/chain_id.jpg differ diff --git a/docs/es/contract/png/cli_wallet.jpg b/docs/es/contract/png/cli_wallet.jpg new file mode 100644 index 0000000..3844bff Binary files /dev/null and b/docs/es/contract/png/cli_wallet.jpg differ diff --git a/docs/es/contract/png/console_print.jpg b/docs/es/contract/png/console_print.jpg new file mode 100644 index 0000000..4d121b9 Binary files /dev/null and b/docs/es/contract/png/console_print.jpg differ diff --git a/docs/es/contract/png/hello_code.jpg b/docs/es/contract/png/hello_code.jpg new file mode 100644 index 0000000..f22671c Binary files /dev/null and b/docs/es/contract/png/hello_code.jpg differ diff --git a/docs/es/contract/png/print.jpg b/docs/es/contract/png/print.jpg new file mode 100644 index 0000000..bbb2b59 Binary files /dev/null and b/docs/es/contract/png/print.jpg differ diff --git a/docs/es/contract/png/right_answer.jpg b/docs/es/contract/png/right_answer.jpg new file mode 100644 index 0000000..6d42100 Binary files /dev/null and b/docs/es/contract/png/right_answer.jpg differ diff --git a/docs/es/contract/png/wrong_answer.jpg b/docs/es/contract/png/wrong_answer.jpg new file mode 100644 index 0000000..0126c61 Binary files /dev/null and b/docs/es/contract/png/wrong_answer.jpg differ diff --git a/docs/es/contract/question.md b/docs/es/contract/question.md new file mode 100644 index 0000000..2a144d3 --- /dev/null +++ b/docs/es/contract/question.md @@ -0,0 +1,302 @@ +# Las opciones adicionales + + +## Inicie la cadena privada localmente + +Refiera a la construcción de la cadena privada + + +## Implemente nodos de red de prueba + + +Red de prueba de referencia + +## Número aleatorio en el contrato + + +En la cadena de bloques, no se pueden generar números aleatorios verificables. Es necesario seleccionar semillas fijas para generar números aleatorios. En general, las secuencias aleatorias se generan mediante el algoritmo hash sha256. Así que la seguridad de números aleatorios, y la selección de semillas es crucial. Si las variables disponibles en la cadena se seleccionan como números aleatorios, como ID de bloque, número de bloque, saldo de activos, etc., una vez que se filtre el algoritmo aleatorio del contrato, el número aleatorio se puede obtener antes de la cadena de bloques, y por lo tanto el negocio se pueden predecir los resultados relacionados con el número aleatorio. Por lo tanto, el algoritmo de número aleatorio debe ser lo más complejo posible, o explorar la posibilidad de obtener datos fuera de la cadena como la semilla del número aleatorio. A continuación se muestra un ejemplo de cómo generar números aleatorios a partir de datos fuera de la cadena: + + +- 1. Cada una de las partes opuestas (Alice y Bob) crea un número aleatorio y calcula su valor hash. + +```bash +#Alice:Cree una cadena aleatoria, como "I am Alice"", y genere el valor hash sha256 +zhaoxiangfei@zhaoxiangfeideMacBook-Pro:~$ echo "I am Alice" | shasum -a 256 +da161d9ee3c116083030737d5a4d478ee1a7654f8ea51e0513020937a9206b0f + +#Bob:Cree una cadena aleatoria, como "I am Bob"", y genere el valor hash sha256 +zhaoxiangfei@zhaoxiangfeideMacBook-Pro:~$ echo "I am Bob" | shasum -a 256 +77f3bfe06cc926329510b60eba56f80a8d32cf35496587d1444fc690c806c0f9 +``` +- 2. Cada entidad de contrapartida genera su propio número aleatorio y valor hash, y ambas partes envían el valor hash a la cadena en la primera interacción + +``` +Una vez que el valor de hash se envía a la cadena, la cadena aleatoria correspondiente al valor de hash también se corrige, pero la otra parte no puede invertir su propia cadena aleatoria de acuerdo con el valor de hash + +``` + +- 3. Ambas partes envían sus propias cadenas aleatorias y el contrato se comprueba con la cadena enviada contra el último valor hash enviado. Dos valores hash y dos cadenas aleatorias se empataron para generar una secuencia hash como un número aleatorio. + + +```bash +sha256("da161d9ee3c116083030737d5a4d478ee1a7654f8ea51e0513020937a9206b0f"+"77f3bfe06cc926329510b60eba56f80a8d32cf35496587d1444fc690c806c0f9"+"I am Alice"+"I am Bob") +``` + +- 4. Genere una secuencia aleatoria mediante dos interacciones. Cuando la primera interacción (cuando se envían los valores de hash de ambos lados, se determina el contenido que se va a enviar para la segunda interacción, pero no se ha determinado la secuencia aleatoria final). Esto evita que la otra parte engañe. + + +## Una combinación de contrato y almacenamiento distribuido + + +El contrato inteligente ofrece la posibilidad de descentralizar la lógica empresarial compleja y puede almacenar datos empresariales relevantes en la cadena para desarrollar DAPP descentralizada. El almacenamiento en la cadena utiliza recursos RAM, que es adecuado para la lectura de alta frecuencia y datos de escritura. El costo del almacenamiento de RAM en la cadena es alto, y algunos archivos grandes no son necesarios para ser almacenados en la memoria RAM en la cadena. El servicio de almacenamiento distribuido proporcionado por GXChian se puede utilizar para hospedar archivos grandes en el almacenamiento BaaS + +## Cálculo de honorarios de contrato + + +Cadena de recursos con el fin de uso razonable de los bloques, cada llamada al contrato inteligente debe estar quemando una tarifa minera, las tasas consisten en tres partes: los gastos básicos (fijo), el costo de memoria (basado en la facturación de uso de almacenamiento persistente), el costo de la CPU (de acuerdo con la llamada la cantidad de tiempo de CPU), el precio de 3 tipos de carga e invocar el límite de CPU del contrato puede ajustarse dinámicamente por Consejo. Reglas de cálculo de honorarios de contrato inteligentes: + +Tarifa de implementación de contrato: cargo base + tamaño del cuerpo de la transacción * tarifa de KB de unidad + +```cpp +deploy_fee = basic_fee+transaction_size*price_per_kb +``` + +Cuota de llamada de contrato: cuota base + uso de memoria + uso de CPU + +```cpp +transaction_fee = basic_fee + ram_usage * price_per_kb + cpu_usage * price_per_ms +``` + + +## La API integrada llama al contrato de ejemplo + + +```cpp +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace graphene; + +class example : public contract +{ + public: + example(uint64_t id) + : contract(id){} + + //current_receiver + // @abi action + void examcurr(){ + uint64_t ins_id = current_receiver(); + print("current contract account id: ", ins_id); + } + + //get_action_asset_id + // @abi action + // @abi payable + void examgetast(){ + uint64_t ast_id = get_action_asset_id(); + print("call action asset id: ",ast_id); + } + + //get_action_asset_amount + // @abi action + // @abi payable + void examgetamo(){ + uint64_t amount = get_action_asset_amount(); + print("call action asset amount: ",amount); + } + + //deposit + // @abi action + // @abi payable + void examdepo(){ + uint64_t ast_id = get_action_asset_id(); + int64_t amount = get_action_asset_amount(); + + print("call action asset id: ",ast_id); + print("\n"); + print("call action asset amount: ",amount); + } + //withdraw_asset + // @abi action + void examwith(uint64_t to, uint64_t asset_id, int64_t amount){ + withdraw_asset(_self,to,asset_id,amount); + print("withdraw_asset example"); + } + + //get_balance + // @abi action + void examgetbl(int64_t account, int64_t asset_id){ + int64_t balance = get_balance(account, asset_id); + print("account balance: ",balance); + } + //sha256 + // @abi action + void examsha25(std::string data){ + checksum256 hash; + sha256(data.c_str(),data.length(),&hash); + printhex(hash.hash,32); + } + + //sha512 + // @abi action + void examsha512(std::string data){ + checksum512 hash; + sha512(data.c_str(),data.length(),&hash); + printhex(hash.hash,64); + } + + //ripemd160 + // @abi action + void examripemd(std::string data){ + checksum160 hash; + ripemd160(data.c_str(),data.length(),&hash); + printhex(hash.hash,20); + } + + //verify_signature (other example: redpacket) + // @abi action + void examverify(std::string data,signature sig,std::string pk){ + bool result; + result = verify_signature(data.c_str(), data.length(), &sig, pk.c_str(), pk.length()); + print("verify result: ",result); + } + + //get_head_block_num + // @abi action + void examgetnum(){ + int64_t head_num = get_head_block_num(); + print("head block num: ",head_num); + } + + //get_head_block_id + // @abi action + void examgetid(){ + checksum160 block_hash; + get_head_block_id(&block_hash); + printhex(block_hash.hash,20); + } + + //get_block_id_for_num + // @abi action + void examidnum(uint64_t num){ + checksum160 block_hash; + get_block_id_for_num(&block_hash,num); + printhex(block_hash.hash,20); + } + + //get_head_block_time + // @abi action + void examgettime(){ + int64_t head_time; + head_time = get_head_block_time(); + print("head block time: ",head_time); + } + + //get_trx_sender + // @abi action + void examgettrx(){ + int64_t sender_id; + sender_id = get_trx_sender(); + print("call action instance id: ",sender_id); + } + + //get_account_id + // @abi action + void examgetacid(std::string data){ + int64_t acc_id; + acc_id = get_account_id(data.c_str(), data.length()); + print("account id: ",acc_id); + } + + //get_account_name_by_id + // @abi action + void examgetname(int64_t accid){ + char data[13]={0}; + int64_t result; + result = get_account_name_by_id(data,13,accid); + prints(data); + } + + //get_asset_id + // @abi action + void examassid(std::string data){ + int64_t assid; + assid = get_asset_id(data.c_str(),data.length()); + print("asset id: ",assid); + } + + //read_transaction + // @abi action + void examreadtrx(){ + int dwsize; + dwsize =transaction_size(); + char* pBuffer = new char[dwsize]; + uint32_t size = read_transaction(pBuffer,dwsize); + print("hex buffer: "); + printhex(pBuffer,dwsize); + delete[] pBuffer; + } + + // @abi action + void examtrxsize(){ + int dwsize; + dwsize =transaction_size(); + print("the size of the serialize trx: ",dwsize); + } + + //expiration + // @abi action + void exampira(){ + uint64_t timenum = expiration(); + print("the expiration time: ", timenum); + } + + //tapos_block_num + // @abi action + void examtapnum(){ + uint64_t tapos_num; + tapos_num = tapos_block_num(); + print("ref block num: ",tapos_num); + } + + //tapos_block_prefix + // @abi action + void examtappre(){ + uint64_t tapos_prefix; + tapos_prefix = tapos_block_prefix(); + print("ref block id: ",tapos_prefix); + } + + //graphene_assert + // @abi action + void examassert(){ + uint64_t number=1; + graphene_assert(number == 1, "wrong!"); + } + + //graphene_assert_message + // @abi action + void examassmsg(){ + uint64_t number=1; + std::string msg = "wrong!!!"; + graphene_assert_message(number == 1, msg.c_str(),msg.length()); + } + + //print + // @abi action + void examprint(){ + print("example example example!!!"); + } +}; + +GRAPHENE_ABI(example,(examcurr)(examgetast)(examgetamo)(examdepo)(examwith)(examgetbl)(examsha25)(examsha512)(examripemd)(examverify)(examgetnum)(examgetid)(examidnum)(examgettime)(examgettrx)(examgetacid)(examgetname)(examassid)(examreadtrx)(examtrxsize)(exampira)(examtapnum)(examtappre)(examassert)(examassmsg)(examprint)) + +``` diff --git a/docs/es/faq/README.md b/docs/es/faq/README.md new file mode 100644 index 0000000..07c558b --- /dev/null +++ b/docs/es/faq/README.md @@ -0,0 +1,80 @@ + +# las preguntas frecuentes del inicio de witness_node + + +## 1. Cómo iniciar el programa witness_node correctamente + Se recomienda iniciar el programa con la siguiente línea de comandos (modifique el valor del parámetro y el número de Puerto apropiadamente según su propia situación): + +```bash +export LC_ALL=C + +nohup ./programs/witness_node/witness_node --data-dir=trusted_node --rpc-endpoint="0.0.0.0:28090" --p2p-endpoint="0.0.0.0:6789" --track-account "\"1.2.241993\"" --max-ops-per-account=-1 --fast-replay 1>nohup.out 2>&1 & + ``` + Si usted comienza como arriba, la salida de la consola será redirigidos a nohup. out, y si hay una excepción en el inicio, usted puede ser que pueda ver nohup. out para localizar el problema. + +## 2. Cómo saber si el witness_node se está ejecutando correctamente + Vea el archivo de registro de fondo `trusted_node/logs/witness.log`, Si el registro continúa recibiendo bloques en la red, indica que el nodo se está ejecutando normalmente, como se muestra a continuación + ``` +2018-08-23T07:10:39 th_a:invoke handle_block handle_block ] Got block: #6939202 time: 2018-08-23T07:10:39 latency: 29 ms from: init6 irreversible: 6939194 (-8) application.cpp:487 +2018-08-23T07:10:42 th_a:invoke handle_block handle_block ] Got block: #6939203 time: 2018-08-23T07:10:42 latency: 30 ms from: init4 irreversible: 6939195 (-8) application.cpp:487 +2018-08-23T07:10:45 th_a:invoke handle_block handle_block ] Got block: #6939204 time: 2018-08-23T07:10:45 latency: 32 ms from: init0 irreversible: 6939195 (-9) application.cpp:487 +2018-08-23T07:10:48 th_a:invoke handle_block handle_block ] Got block: #6939205 time: 2018-08-23T07:10:48 latency: 34 ms from: init5 irreversible: 6939197 (-8) application.cpp:487 +2018-08-23T07:10:51 th_a:invoke handle_block handle_block ] Got block: #6939206 time: 2018-08-23T07:10:51 latency: 34 ms from: init1 irreversible: 6939198 (-8) application.cpp:487 +2018-08-23T07:10:54 th_a:invoke handle_block handle_block ] Got block: #6939207 time: 2018-08-23T07:10:54 latency: 36 ms from: bob irreversible: 6939199 (-8) application.cpp:487 +2018-08-23T07:10:57 th_a:invoke handle_block handle_block ] Got block: #6939208 time: 2018-08-23T07:10:57 latency: 37 ms from: init1 irreversible: 6939200 (-8) application.cpp:487 +2018-08-23T07:11:00 th_a:invoke handle_block handle_block ] Got block: #6939209 time: 2018-08-23T07:11:00 latency: 39 ms from: init7 irreversible: 6939200 (-9) application.cpp:487 +2018-08-23T07:11:03 th_a:invoke handle_block handle_block ] Got block: #6939210 time: 2018-08-23T07:11:03 latency: 41 ms from: bao irreversible: 6939201 (-9) application.cpp:487 +2018-08-23T07:11:06 th_a:invoke handle_block handle_block ] Got block: #6939211 time: 2018-08-23T07:11:06 latency: 41 ms from: init8 irreversible: 6939202 (-9) application.cpp:487 +2018-08-23T07:11:09 th_a:invoke handle_block handle_block ] Got block: #6939212 time: 2018-08-23T07:11:09 latency: 44 ms from: init2 irreversible: 6939203 (-9) application.cpp:487 +2018-08-23T07:11:12 th_a:invoke handle_block handle_block ] Got block: #6939213 time: 2018-08-23T07:11:12 latency: 45 ms from: init4 irreversible: 6939204 (-9) + ``` +## 3. Error de sincronización de bloque + Vea el archivo de registro de fondo `trusted_node/logs/witness.log`, si el registro continúa reportando un error, como `"unlinkable block"`, `"block does not link to known chain"`, es un error de sincronización de bloques. + + Soluciones: + * Cierre el programa primero, reinícielo con `--replay-blockchain`, espere a que finalice el inicio y observe si el witness.log es normal. + * Si todavía falla, podría ser una excepción de sincronización de blockchain, o el archivo blockchain local podría estar dañado. Debe detener el programa witness_node y, a continuación, eliminar el trusted_node y reiniciar el witness_node. + * O en lugar de quitar el directorio trusted_node, inicie el comando con el parámetro --resync-blockchain y el bloque se resincronizará. +## 4. Cómo cerrar el witness_node normalmente + witness_node escribe todos los datos en la memoria como un objeto. Cuando el programa sale normalmente, los datos en la memoria se escribirán en el disco. Así que no puede cerrar el proceso por la fuerza, o la base de datos en memoria va a ir mal. + * Si el witness_node no se ejecuta en segundo plano, ejecute Ctrl + C durante una vez y espere a que el programa guarde los datos de memoria y se sale automáticamente. + * Si el witness_node se está ejecutando en segundo plano, ejecute `kill -s SIGINT $(pgrep witness_node)` y espere a que el programa guarde los datos de memoria. No puede usar Kill-9, o el siguiente lanzamiento reconstruirá el índice y comenzará lentamente. +## El proceso de witness_node es normal pero no recibe bloques de la red + + * Compruebe el archivo de registro en segundo plano y no busque ningún mensaje de error, y el nodo no recibe un nuevo bloque de la red. Esto es probablemente porque la versión del witness_node es antigua. Por favor, visite la página de lanzamiento de [github](https://github.com/gxchain/gxb-core/releases/latest) para descargar el paquete más reciente. + * Puede comprobar el número de versión del witness_node con el parámetro-v : + + ```bash + $./programs/witness_node/witness_node -v + Version: 1.0.180713-379-g4c9a2f4 + SHA: 4c9a2f4e168503abe3ce1432c699f88b8babe356 + Timestamp: 4 hours ago + SSL: OpenSSL 1.0.2o 27 Mar 2018 + Boost: 1.67 + Websocket++: 0.7.0 + ``` +## 6.¿Qué sistema operativo utiliza BP y cuáles son los requisitos para el hardware, incluido el ancho de banda? + * ubuntu14,04 sistema de 64 bits + * 4 núcleos 32G memoria disco duro 200G, 50MB + ancho de banda, de acuerdo con el flujo de facturación, doble copia de seguridad ante desastres + * Puede utilizar un servidor en la nube + +## 7. witness_node iniciado con un puerto de informe de errores + Compruebe que el servidor ha iniciado más de un witness_node, lo que resulta en conflictos de puerto. + +```bash +ps xf | grep witness_node +``` + Si se ha iniciado más de un witness_node, por favor apague y reinicie:: +```bash +for i in $(pgrep witness_node); do echo kill -9 $i; done +``` + +## 8. Error de inicio de witness_node, no hay registro para el proceso +Modifique el archivo config. ini local de la siguiente manera: +``` +[logger.default] +level=debug +appenders=stderr,FILE +``` +A continuación, reinicie y el mensaje de error se imprimirá en la consola + diff --git a/docs/es/guide/README.md b/docs/es/guide/README.md new file mode 100644 index 0000000..b42c304 --- /dev/null +++ b/docs/es/guide/README.md @@ -0,0 +1,142 @@ +# Inicio rapido + +## Conoce GXChain + + +GXChain es una cadena pública de gobierno descentralizada, de alto rendimiento y ecológica. En el ecosistema de GXChain, el consejo, el nodo de confianza pública y los tenedores de la moneda completan conjuntamente el gobierno de la cadena. + + +- **La Junta de Directores**:Los **11** miembros principales del nodo de confianza pública fueron elegidos como miembros de la Junta de Directores de GXChain, principalmente responsables de la modificación de los parámetros dinámicos de la cadena de bloques. +- **Nodo de crédito público**:responsable de empaquetar bloques, verificar transacciones, contar los votos cada **1** hora y seleccionar los primeros **21** como nodos de confianza pública de acuerdo con el número de votos. +- **Titular**:Una persona o institución que posee cualquier número de GXC. El titular puede participar en la Ecología de GXChain y votar por el nodo de confianza pública. + +La capa inferior de GXChain utiliza una arquitectura de grafeno basada en el mecanismo de consenso de DPoS para un mayor rendimiento. + +- **Tiempo de generación del bloque**:**3** s +- **TPS**:mil nivel + +## Requerimientos ambientales + +- Sistema: **macOS / Ubuntu 14.04 64-bit**, **4.4.0-63-genérico** arriba del kernel +- Memoria: 16GB+ +- Disco duro: 100GB+ +- Red: 20MB+ ancho de banda + +::: warning Instalacion dependiente + +* Instalar ntp +``` bash +sudo apt-get install ntp +# macOS instalar ntp: brew install ntp +``` + +* instalar libstdc++-7-dev +```bash +# Ubuntu sistema se lo necesita instalar, macOS no se necesita +apt-get update +apt-get install software-properties-common +add-apt-repository ppa:ubuntu-toolchain-r/test +apt-get update +apt-get install libstdc++-7-dev +``` + +::: + +## Instalacion de nodos + + +Los siguientes pasos demuestran el inicio del nodo de red principal. + +- Si eres un desarrollador y quieres una experiencia rápida, ve a la [red de prueba](../advanced/testnet.html) +- Si desea construir una cadena privada basada en GXChain, puede ir a la [cadena privada para construir](../advanced/private_chain.html) + + +### 1. Descargar el paquete de lanzamiento + +``` bash +# La ejecución de este script de shell descargará automáticamente el último programa web principal de github y lo extraerá al directorio actual. +curl 'https://raw.githubusercontent.com/gxchain/gxb-core/dev_master/script/gxchain_install.sh' | bash +``` + +### 2. Iniciar nodo, sincronizar datos + +``` bash +nohup ./programs/witness_node/witness_node --data-dir=trusted_node --rpc-endpoint="127.0.0.1:28090" 1>nohup.out 2>&1 & +``` + +El comando anterior: +- Comenzó a escuchar un servicio RPC el `127.0.0.1:28090` +- La información de bloque especificada se guarda en el directorio `./trusted_node`. + +::: tip Recordatorio amistoso +- El bloque de sincronización tarda aproximadamente **30 horas**, lo que, por supuesto, tiene algo que ver con su red. +- Antes de que se complete la sincronización de bloques, solo tiene que esperar pacientemente, durante el cual puede leer la documentación. +::: + +### 3. Revisar el registro y esperar a que se sincronicen los datos + +``` bash +tail -f trusted_node/logs/witness.log +``` + +Una vez que se completa la sincronización de nodos, el registro se ve así (reciba 1 bloque nuevo de la red cada 3 segundos): + +``` bash +2018-06-28T03:43:03 th_a:invoke handle_block handle_block ] Got block: #10731531 time: 2018-06-28T03:43:03 latency: 60 ms from: miner11 irreversible: 10731513 (-18) application.cpp:489 +2018-06-28T03:43:06 th_a:invoke handle_block handle_block ] Got block: #10731532 time: 2018-06-28T03:43:06 latency: 16 ms from: taffy irreversible: 10731515 (-17) application.cpp:489 +2018-06-28T03:43:09 th_a:invoke handle_block handle_block ] Got block: #10731533 time: 2018-06-28T03:43:09 latency: 49 ms from: david12 irreversible: 10731515 (-18) application.cpp:489 +2018-06-28T03:43:12 th_a:invoke handle_block handle_block ] Got block: #10731534 time: 2018-06-28T03:43:12 latency: 42 ms from: miner6 irreversible: 10731516 (-18) application.cpp:489 +2018-06-28T03:43:15 th_a:invoke handle_block handle_block ] Got block: #10731535 time: 2018-06-28T03:43:15 latency: 10 ms from: sakura irreversible: 10731516 (-19) application.cpp:489 +2018-06-28T03:43:18 th_a:invoke handle_block handle_block ] Got block: #10731536 time: 2018-06-28T03:43:18 latency: 57 ms from: miner9 irreversible: 10731517 (-19) application.cpp:489 +2018-06-28T03:43:21 th_a:invoke handle_block handle_block ] Got block: #10731537 time: 2018-06-28T03:43:21 latency: 56 ms from: robin-green irreversible: 10731517 (-20) application.cpp:489 +2018-06-28T03:43:24 th_a:invoke handle_block handle_block ] Got block: #10731538 time: 2018-06-28T03:43:24 latency: 17 ms from: kairos irreversible: 10731522 (-16) application.cpp:489 +2018-06-28T03:43:27 th_a:invoke handle_block handle_block ] Got block: #10731539 time: 2018-06-28T03:43:27 latency: 21 ms from: dennis1 irreversible: 10731524 (-15) application.cpp:489 +2018-06-28T03:43:30 th_a:invoke handle_block handle_block ] Got block: #10731540 time: 2018-06-28T03:43:30 latency: 17 ms from: aaron irreversible: 10731524 (-16) application.cpp:489 +2018-06-28T03:43:33 th_a:invoke handle_block handle_block ] Got block: #10731541 time: 2018-06-28T03:43:33 latency: 23 ms from: caitlin irreversible: 10731526 (-15) application.cpp:489 +``` + +## Registro de cuenta + +GXChain utiliza un modelo de cuenta e introduce un mecanismo de registro de referencias, por lo que registrar una cuenta en GXChain requiere los siguientes tres elementos: + +- **Referente**,el referente es una cuenta existente en la cadena y usará su nombre de cuenta y clave pública para ayudarlo a registrar una cuenta. +- **El nombre de la cuenta**,el nombre de la cuenta es único en la cadena, así que recuerde que en GXChain, el nombre de la cuenta es la dirección (por ejemplo, gxchain-genius) +- **Clave pública de ECC**,comenzando con GXC, clave pública de ECC codificada en Base64 (¿Cómo generar una clave pública? No se preocupe, mire hacia atrás) + +Hay dos formas de completar el registro de su cuenta: + +### 1. Billetera online + +Complete los pasos anteriores en la interfaz utilizando la cartera en línea [https://wallet.gxb.io](https://wallet.gxb.io) + + +### 2. Registro manual. + +Se recomienda que los desarrolladores con mayores requisitos de seguridad de clave privada utilicen este método para completar el registro y garantizar que la clave privada esté fuera de línea. + +#### Paso 1: genere un par de claves públicas y privadas a través de cli_wallet + +``` bash +./programs/cli_wallet/cli_wallet --suggest-brain-key +{ + "brain_priv_key": "SHAP CASCADE AIRLIKE WRINKLE CUNETTE FROWNY MISREAD MOIST HANDSET COLOVE EMOTION UNSPAN SEAWARD HAGGIS TEENTY NARRAS", + "wif_priv_key": "5J2FpCq3UmvcodkCCofXSNvHYTodufbPajwpoEFAh2TJf27EuL3", + "pub_key": "GXC75UwALPEFECfHLjHyNSxCk1j7XzSvApQiXKEbanWgr7yvXXbdG" +} +``` + +::: tip Explicación del campo +- brain_priv_key: mnemonic, el texto original de la clave privada, que puede ser restaurado por la mnemotécnica +- wif_priv_key: clave privada, utilizada en el programa +- pub_key: clave pública para el registro en la cadena. +::: + +#### Paso 2: Completa el registro de la cuenta a través del grifo. + + +1. Quiero un nombre de cuenta único (account_name), como `gxchain-genius` +2. Reemplace `` y `` en el comando curl a continuación y ejecútelo en el terminal: + +``` bash +curl 'https://opengateway.gxb.io/account/register' -H 'Content-type: application/json' -H 'Accept: application/json’ -d ‘{“account”:{“name”:””,”owner_key”:””,”active_key”:””,”memo_key”:””,”refcode”:null,”referrer”:null}}’ +``` diff --git a/docs/es/guide/apis.md b/docs/es/guide/apis.md new file mode 100644 index 0000000..7f51dfb --- /dev/null +++ b/docs/es/guide/apis.md @@ -0,0 +1,1860 @@ +# API Reference + +Los nodos de GXChain proporcionan interfaces WebSocket y JSONRPC + +## Cadena relacionada + +### `get_chain_id` +Obtener la cadena ID + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_chain_id
API Parameters
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_chain_id", []], + "id": 1 +}' https://node1.gxb.io/rpc +``` +**response:** +```json +{ + "id":1, + "jsonrpc":"2.0", + "result":"4f7d07969c446f8342033acb3ab2ae5044cbe0fde93db02de75bd17fa8fd84b8" // chain id +} +``` + +### `get_dynamic_global_properties` +Obtenga el objeto dinámico global, incluido el número de bloque más reciente, el último id de bloque, el tiempo de encabezado de bloque y otra información + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_dynamic_global_properties
API Parameters
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_dynamic_global_properties", []], + "id": 1 +}' https://node1.gxb.io/rpc +``` + +**response:** +```json +{ + "id":1, + "jsonrpc":"2.0", + "result":{ + "id":"2.1.0", + "head_block_number":16757465, // el número de bloque más reciente + "head_block_id":"00ffb2d9f6e344f2190a8dfba58baaadd49e76c4", // el último id de bloque + "time":"2019-01-28T06:08:00", // el tiempo de encabezado de bloque + "current_witness":"1.6.52", // Empaquete el witness id del head block actual + "next_maintenance_time":"2019-01-28T06:40:00", // Siguiente tiempo de ciclo de mantenimiento + "last_budget_time":"2019-01-28T05:40:00", // Último tiempo de ciclo de mantenimiento + "witness_budget":3065824, // El presupuesto de nodo restante para el ciclo de mantenimiento actual + "accounts_registered_this_interval":2, + "recently_missed_count":0, // El último bloque que falta de un nodo + "current_aslot":16958091, + "recent_slots_filled":"340282366920938463463374607431768211455", + "dynamic_flags":0, + "last_irreversible_block_num":16757449 // El último número de bloque irreversible + } +} +``` + + +## Bloque relacionado + +### `get_block` + +Obtener información de bloque por número de bloque + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_block
API Parameters
Parámetro de APIEspecificación de parámetro de API
block_numNúmero de bloque/altura de bloque
+ + +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_block", [10000]], + "id": 1 +}' https://node1.gxb.io/rpc +``` + +**response:** +```json +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "previous": "0000270f5b219bc4c6996f2cca89b23ef653a2b0", // block id(block hash) del bloque anterior + "timestamp": "2017-06-10T22:53:45", // timestamp del bloque actual + "witness": "1.6.23", // Empaquetar el witness id del bloque actual + "transaction_merkle_root": "0000000000000000000000000000000000000000", // En el bloque actual, la raíz de merkle de la transacción + "extensions": [], + "witness_signature": "204e95ba3f871d8f670cc8088d5f563704c9c0c8acd42a80077bd7c6a47ecde095633e6a614c7f73830d972c3b617d5c01e8e0e151bfc489a327103597d3f0c244", // la firma del witness + "transactions": [], // Lista de transacciones + "block_id": "000027100ef5386d4ea4481dc302401de66fe358", // el block id actual + "signing_key": "GXC7ouC3miJyKrLf1XyeyDv6u5W9Q8BT3WdbJbJYACiFm2Zx8vPna", // el signing key de witness actual + "transaction_ids": [] // tx id correspondiente a la lista de Trading + } +} +``` + +### `get_block_header` + +Obtener información de bloque por número de bloque + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_block_header
API Parameters
Parámetro de APIEspecificación de parámetro de API
block_numNúmero de bloque/altura de bloque
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_block_header", [10000]], + "id": 1 +}' https://node1.gxb.io/rpc +``` + +**response:** +```json +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "previous": "0000270f5b219bc4c6996f2cca89b23ef653a2b0", // block id(block hash) del bloque anterior + "timestamp": "2017-06-10T22:53:45", // timestamp del bloque actual + "witness": "1.6.23", // Empaquetar el witness id del bloque actual + "transaction_merkle_root": "0000000000000000000000000000000000000000", // En el bloque actual, la raíz de merkle de la transacción + "extensions": [] + } +} +``` +## Transacción relacionada + +### `get_transaction_hex` + +Devuelve la cadena serializada de la transacción en formato hexadecimal + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_transaction_hex
API Parameters
Parámetro de APIEspecificación de parámetro de API
transactionCuerpo de transacción
+ +#### Ejemplo + +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_transaction_hex", [{"ref_block_num":53237,"ref_block_prefix":892361345,"expiration":"2019-03-07T06:07:21","operations":[[0,{"fee":{"amount":50000,"asset_id":"1.3.1"},"from":"1.2.17","to":"1.2.6","amount":{"amount":100000,"asset_id":"1.3.1"},"extensions":[]}]],"extensions":[],"signatures":[]}]], "id": 1 +}' https://node1.gxb.io/rpc +``` + +**response:** +``` +{"id":1,"jsonrpc":"2.0","result":"f5cf815a303519b5805c010050c3000000000000011106a0860100000000000100000000"} +``` + +## Objetos relacionados + +En GXChain, almacene diferentes tipos de datos por diferentes objetos. Haga clic aquí para ver [tipos de objeto en GXChain] (objetos ./#_2-gxchain) + +### `get_objects` + +Obtenga la información del objeto en función del ID del objeto + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_objects
API Parameters
Parámetro de APIEspecificación de parámetro de API
[id del objeto]Matriz, puede pasar en varios IDs correspondientes
+ +#### Ejemplo + +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_objects", [["1.3.1","2.3.1"]]], "id": 1 +}' https://node1.gxb.io/rpc +``` + +**response:** +```json +{ + "id": 1, + "jsonrpc": "2.0", + "result": [{ // 1.3.1对象 + "id": "1.3.1", + "symbol": "GXC", + "precision": 5, + "issuer": "1.2.0", + "options": { + "max_supply": "10000000000000", + "market_fee_percent": 0, + "max_market_fee": 0, + "issuer_permissions": 69, + "flags": 0, + "core_exchange_rate": { + "base": { + "amount": 100000, + "asset_id": "1.3.1" + }, + "quote": { + "amount": 100000, + "asset_id": "1.3.1" + } + }, + "whitelist_authorities": [], + "blacklist_authorities": [], + "whitelist_markets": [], + "blacklist_markets": [], + "description": "{\"main\":\"GXC es el token emitido por la Fundación GXB en GXChain. No sólo tiene valor circulante, sino que también necesita pagar o quemar GXC al desarrollar, autenticar y usar el servicio de cadena (como la tarifa del minero para transferir dinero en la cadena) y el uso del servicio BaaS. GXC es el token utilizado por la aplicación en la cadena. En la Ciudad de Block, GXC también se puede utilizar convenientemente para el pago y la liquidación. Por ejemplo, los residentes utilizan GXC para liquidar cuentas entre sí, los servicios públicos urbanos deben ser liquidados con GXC, y los servicios prestados por las empresas necesitan ser comprados con GXC\",\"short_name\":\"\",\"market\":\"\"}", + "extensions": [] + }, + "dynamic_asset_data_id": "2.3.1" + }, { // 2.3.1 objeto + "id": "2.3.1", + "current_supply": "9958303550217", + "confidential_supply": 0, + "accumulated_fees": 0, + "fee_pool": 0 + }] +} +``` + +## Cuenta relacionada + + +### `get_account_count` + +Obtiene el número total de cuentas de la cadena + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_account_count
API Parameters
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_account_count", []], + "id": 1 +}' https://node1.gxb.io/rpc +``` + +**response:** +```json +{ + "id": 1, + "jsonrpc": "2.0", + "result": 1118627 // el número total de cuentas de la cadena +} +``` + +### `get_account_by_name` + +Obtener información de 'cuenta' de acuerdo con 'account_name', * * no contiene la información de * * objetos asociados, tales como saldo de activos de cuenta, saldo que se deben descongelar, saldo congelado de plan de lealtad, etc +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_account_by_name
API Parameters
Parámetro de APIEspecificación de parámetro de API
account_nameNombre de cuenta
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_account_by_name", ["nathan"]], + "id": 1 +}' https://node1.gxb.io/rpc +``` +**response:** +```json +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "id": "1.2.17", // id de cuanta + "membership_expiration_date": "2106-02-07T06:28:15", // no es 1970-01-01T00:00:00, La membresía de vida + "merchant_expiration_date": "1970-01-01T00:00:00", // no es1970-01-01T00:00:00, Comerciantes + "datasource_expiration_date": "1970-01-01T00:00:00", // no es1970-01-01T00:00:00, Origen de datos + "data_transaction_member_expiration_date": "1970-01-01T00:00:00", // 不为1970-01-01T00:00:00, Autoridad de validación de transacciones está disponible en DES 1,0 + "registrar": "1.2.17", // El registrante de cuenta + "referrer": "1.2.17", // El recomendador de cuenta + "lifetime_referrer": "1.2.17", // El recomendador de miembro de la vida + "merchant_auth_referrer": "1.2.0", // El recomendador del comerciante + "datasource_auth_referrer": "1.2.0", // El recomendador del origen de datos + "network_fee_percentage": 2000, // Poundage compartido, la cuota de red + "lifetime_referrer_fee_percentage": 8000, // Poundage compartido, la cuota del recomendador de miembro de la vida + "referrer_rewards_percentage": 0, // Poundage compartido, la cuota del recomendador + "name": "nathan", // Nombre de cuenta + "vm_type": "", //Tipo de vm, campos reservados + "vm_version": "", // Versión de vm, campos reservados + "code": "", // El código para las cuentas de contrato aplicables + "code_version": "", // El código hash + "abi": { //la abi corresponde de code, que se aplica a la cuenta de contrato aplicable + "version": "gxc::abi/1.0", + "types": [], + "structs": [], + "actions": [], + "tables": [], + "error_messages": [], + "abi_extensions": [] + }, + "owner": { // Permisos de propietario de cuenta, que se pueden usar para modificar los permisos de cuenta + "weight_threshold": 1, + "account_auths": [], + "key_auths": [ + ["GXC6cdTzGgTLv7VohhT76o82WmZmTwvijrkr5hJ3k8G2dEREee6wV", 1] + ], + "address_auths": [] + }, + "active": { // Permisos activos en las cuentas, que se pueden usar para gastar fondos de cuenta + "weight_threshold": 1, + "account_auths": [], + "key_auths": [ + ["GXC6cdTzGgTLv7VohhT76o82WmZmTwvijrkr5hJ3k8G2dEREee6wV", 1] + ], + "address_auths": [] + }, + "options": { + "memo_key": "GXC6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", // memo key + "voting_account": "1.2.5", + "num_witness": 0, + "num_committee": 0, + "votes": [], + "extensions": [] + }, + "statistics": "2.6.17", // Objeto de estadísticas de cuenta + "whitelisting_accounts": [], + "blacklisting_accounts": [], + "whitelisted_accounts": [], + "blacklisted_accounts": [], + "cashback_vb": "1.13.246", // ID de objeto de cashback + "owner_special_authority": [0, {}], + "active_special_authority": [0, {}], + "top_n_control_flags": 0 + } +} +``` + +### `get_full_accounts` + +Obtener información completa de la cuenta de acuerdo con ' account_ids o account_names ', * * contiene información sobre * * objetos asociados, tales como saldo de activos de cuenta, saldo congelado, etc. +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_full_accounts
API Parameters
Parámetro de APIEspecificación de parámetro de API
[Nombre o ID de cuanta ]Matriz, para pasar el nombre de cuenta o el ID de cuenta
bool tipoSuscribirse o no
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_full_accounts", [["blockcitybp"],false]], + "id": 1 +}' https://node1.gxb.io/rpc +``` +**response:** +```json +{ + "id":1, + "jsonrpc":"2.0", + "result":[ + [ + "blockcitybp", + { + "account":{ + "id":"1.2.1089881", + "membership_expiration_date":"2106-02-07T06:28:15", // no es 1970,es cuenta de miembro de vida + "merchant_expiration_date":"1970-01-01T00:00:00", // no es 1970, es comerciantes + "datasource_expiration_date":"1970-01-01T00:00:00", // no es 1970, es origen de datos + "data_transaction_member_expiration_date":"1970-01-01T00:00:00", + "registrar":"1.2.1089881", // El registrante de cuenta + "referrer":"1.2.1089881", // El recomendador de cuenta + "lifetime_referrer":"1.2.1089881", + "merchant_auth_referrer":"1.2.0", + "datasource_auth_referrer":"1.2.0", + "network_fee_percentage":2000, + "lifetime_referrer_fee_percentage":8000, + "referrer_rewards_percentage":1000, + "name":"blockcitybp", // Nombre de cuenta + "vm_type":"", + "vm_version":"", + "code":"", // code no está vacío, es una cuenta de contrato inteligente + "code_version":"", + "abi":{ + "version":"gxc::abi/1.0", + "types":[ + + ], + "structs":[ + + ], + "actions":[ + + ], + "tables":[ + + ], + "error_messages":[ + + ], + "abi_extensions":[ + + ] + }, + "owner":{ + "weight_threshold":1, + "account_auths":[ + + ], + "key_auths":[ + [ + "GXC8XrrSD9LE4UuUvB1QtTA1EhUfjQeJLZwgeP7br56Koh1zrxez7", + 1 + ] + ], + "address_auths":[ + + ] + }, + "active":{ + "weight_threshold":1, + "account_auths":[ + + ], + "key_auths":[ + [ + "GXC8XrrSD9LE4UuUvB1QtTA1EhUfjQeJLZwgeP7br56Koh1zrxez7", + 1 + ] + ], + "address_auths":[ + + ] + }, + "options":{ + "memo_key":"GXC8XrrSD9LE4UuUvB1QtTA1EhUfjQeJLZwgeP7br56Koh1zrxez7", + "voting_account":"1.2.5", + "num_witness":0, + "num_committee":0, + "votes":[ + + ], + "extensions":[ + + ] + }, + "statistics":"2.6.1089881", + "whitelisting_accounts":[ + + ], + "blacklisting_accounts":[ + + ], + "whitelisted_accounts":[ + + ], + "blacklisted_accounts":[ + + ], + "cashback_vb":"1.13.278", + "owner_special_authority":[ + 0, + { + + } + ], + "active_special_authority":[ + 0, + { + + } + ], + "top_n_control_flags":0 + }, + "statistics":{ + "id":"2.6.1089881", + "owner":"1.2.1089881", + "most_recent_op":"2.9.201931750", + "total_ops":13, + "removed_ops":0, + "total_core_in_orders":0, + "lifetime_fees_paid":5153414, + "pending_fees":0, + "pending_vested_fees":0 + }, + "registrar_name":"blockcitybp", + "referrer_name":"blockcitybp", + "lifetime_referrer_name":"blockcitybp", + "votes":[ + + ], + "cashback_balance":{ // El saldo devuelto, es parte del saldo que se va a descongelar + "id":"1.13.278", + "owner":"1.2.1089881", + "balance":{ + "amount":1932, // La precisión de amount es 5, convertida a la cantidad normal es1932/100000 + "asset_id":"1.3.1" // 1.3.1 correspondiente GXC + }, + "policy":[ // Estrategia de descongelamiento, 0 significa lineal, 1 significa día de la moneda + 1, + { + "vesting_seconds":2592000, + "start_claim":"1970-01-01T00:00:00", + "coin_seconds_earned":"5007744000", + "coin_seconds_earned_last_update":"2019-01-16T07:40:00" + } + ] + }, + "balances":[ // El saldo + { + "id":"2.5.456853", + "owner":"1.2.1089881", + "asset_type":"1.3.1", + "balance":265386 + } + ], + "locked_balances":[ + + ], + "vesting_balances":[ // Saldo que se deben descongelar + { + "id":"1.13.171", + "owner":"1.2.1089881", + "balance":{ + "amount":0, + "asset_id":"1.3.1" + }, + "policy":[ + 1, + { + "vesting_seconds":7776000, + "start_claim":"1970-01-01T00:00:00", + "coin_seconds_earned":"0", + "coin_seconds_earned_last_update":"2018-12-27T03:04:21" + } + ] + }, + { + "id":"1.13.259", + "owner":"1.2.1089881", + "balance":{ + "amount":265747140, + "asset_id":"1.3.1" + }, + "policy":[ + 1, + { + "vesting_seconds":86400, + "start_claim":"1970-01-01T00:00:00", + "coin_seconds_earned":"22960140940800", + "coin_seconds_earned_last_update":"2019-01-28T06:11:57" + } + ] + }, + { + "id":"1.13.278", + "owner":"1.2.1089881", + "balance":{ + "amount":1932, + "asset_id":"1.3.1" + }, + "policy":[ + 1, + { + "vesting_seconds":2592000, + "start_claim":"1970-01-01T00:00:00", + "coin_seconds_earned":"5007744000", + "coin_seconds_earned_last_update":"2019-01-16T07:40:00" + } + ] + } + ], + "pledge_balances":[ // El saldo de activos hipotecados por el nodo de GXB + { + "id":"1.26.1", + "owner_account":"1.2.1089881", + "amount":{ + "amount":1000000000, + "asset_id":"1.3.1" + } + } + ], + "limit_orders":[ + + ], + "call_orders":[ + + ], + "settle_orders":[ + + ], + "proposals":[ + + ], + "assets":[ + + ], + "withdraws":[ + + ] + } + ] + ] +} +``` + +### `is_account_registered` +Compruebe si el nombre de cuenta está registrado. Devuelve true si se registra, false si no está registrado o si el nombre de cuenta es ilegal + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameis_account_registered
API Parameters
Parámetro de APIEspecificación de parámetro de API
account_nameNombre de cuenta
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "is_account_registered", ["nathan"]], + "id": 1 +}' https://node1.gxb.io/rpc +``` + +**response:** +```json +{ + "id": 1, + "jsonrpc": "2.0", + "result": true // true indica que la cuenta está registrada +} +``` + +### `get_key_references` +En función de la clave pública, consulte la cuenta asociada y devuelva el id de cuenta asociado + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_key_references
API Parameters
Parámetro de APIEspecificación de parámetro de API
[la clave pública]Matriz, a pasar una serie de claves públicas
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_key_references", [["GXC7mmfnZWUYtz2tjNGqduZRe2w5x79GCjuoMiVkmEGRE94Vq7gAo"]]], + "id": 1 +}' https://node1.gxb.io/rpc +``` + +**response:** +```json +{ + "id": 1, + "jsonrpc": "2.0", + "result": [ + ["1.2.26", "1.2.26"] // Account id relacionado con la clave pública + ] +} +``` + +## Activos relacionados + +### `list_assets` + +Consulte el recurso para devolver un objeto de activo mayor que el parámetro pasado en + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Namelist_assets
API Parameters
Parámetro de APIEspecificación de parámetro de API
El nombre del activoUn símbolo de activo o una primera cadena, por ejemplo G
limitNúmero de resultados devueltos
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "list_assets", ["G", 2]], + "id": 1 +}' https://node1.gxb.io/rpc +``` + +**response:** +```json +{ + "id": 1, + "jsonrpc": "2.0", + "result": [{ + "id": "1.3.11", // Devuelve el activo1.3.11 + "symbol": "GBA", // El nombre de activo GBA + "precision": 5, // Precisión + "issuer": "1.2.1110589", // El emisor de activos + "options": { + "max_supply": "200000000000000", // Máximo suministro de activos + "market_fee_percent": 0, + "max_market_fee": 0, + "issuer_permissions": 0, + "flags": 0, + "core_exchange_rate": { // Tipo de cambio con GXC + "base": { + "amount": 100000, + "asset_id": "1.3.1" + }, + "quote": { + "amount": 1000000, + "asset_id": "1.3.11" + } + }, + "whitelist_authorities": [], + "blacklist_authorities": [], + "whitelist_markets": [], + "blacklist_markets": [], + "description": "{\"main\":\"Green Building Asset,o GBA, es la distribución gratuita del 50 por ciento de los activos verdes basados en la cadena de cartas públicas.\",\"market\":\"\"}", + "extensions": [] + }, + "dynamic_asset_data_id": "2.3.11" // La propiedad dinámica correspondiente al activo corresponde al ID + }, { + "id": "1.3.5", // activo1.3.5 + "symbol": "GCNY", // Nombre de activo GCNY + "precision": 5, + "issuer": "1.2.785392", + "options": { + "max_supply": "1000000000000000", + "market_fee_percent": 0, + "max_market_fee": 0, + "issuer_permissions": 79, + "flags": 0, + "core_exchange_rate": { + "base": { + "amount": 1000000, + "asset_id": "1.3.1" + }, + "quote": { + "amount": 100000, + "asset_id": "1.3.5" + } + }, + "whitelist_authorities": [], + "blacklist_authorities": [], + "whitelist_markets": [], + "blacklist_markets": [], + "description": "", + "extensions": [] + }, + "dynamic_asset_data_id": "2.3.5" + }] +} +``` + +### `lookup_asset_symbols` + +Obtener detalles de activos por nombre de activo + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Namelookup_asset_symbols
API Parameters
Parámetro de APIEspecificación de parámetro de API
[Nombre de activo]Matriz, símbolo de activo o primera cadena, por ejemplo GXC
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "lookup_asset_symbols", [["GXC"]]], + "id": 1 +}' https://node1.gxb.io/rpc +``` + +**response:** +El resultado es el mismo que list_assets + +### `get_account_balances` +Obtenga el saldo de la cuenta en función del ID de cuenta y del ID de activo, y devuelva el saldo de activos completo si no se especifica el ID de activo + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_account_balances
API Parameters
Parámetro de APIEspecificación de parámetro de API
account_idid de cuenta
[asset id]Matriz, id de activo
+ +####Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_account_balances", ["1.2.42", ["1.3.0", "1.3.1"]]], + "id": 1 +}' https://node1.gxb.io/rpc + +``` + +**response:** +```json +{ + "id":1, + "jsonrpc":"2.0", + "result":[ + { + "amount":"79795227868", + "asset_id":"1.3.0" // 1.3.0 es activo de NULL + }, + { + "amount":"3949999988445", // La precisión de los activos de GXChain es 5 y la cantidad real es 39499999.88445 + "asset_id":"1.3.1" // 1.3.1 es activo de GXChain + } + ] +} +``` + +### `get_named_account_balances` + +Obtenga el saldo de la cuenta en función del nombre de cuenta y el ID de activo, y devuelva el saldo de activos completo si no se especifica el ID de activo + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_named_account_balances
API Parameters
Parámetro de APIEspecificación de parámetro de API
account_nameNombre de cuenta
[asset id]Matriz, id de activo
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_named_account_balances", ["gxbfoundation", ["1.3.0", "1.3.1"]]], + "id": 1 +}' https://node1.gxb.io/rpc + +``` + +**response:** +```json +{ + "id": 1, + "jsonrpc": "2.0", + "result": [{ + "amount": "79795227868", // 1.3.0 El saldo de activo + "asset_id": "1.3.0" + }, { + "amount": "3949999988445", // 1.3.1 El saldo de activo, es el activo de GXChain, como la precisión de los activos de GXChain es 5, la cantidad real es3949999988445 / 100000 + "asset_id": "1.3.1" + }] +} +``` + +### `get_vesting_balances` + +Obtiene todos los saldos que se deben descongelar de la cuenta en función del identificador de cuenta + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_vesting_balances
API Parameters
Parámetro de APIEspecificación de parámetro de API
account_idid de cuenta
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_vesting_balances", ["1.2.748971"]], + "id": 1 +}' https://node1.gxb.io/rpc +``` + +**response:** +```json +{ + "id":1, + "jsonrpc":"2.0", + "result":[ + { + "id":"1.13.89", + "owner":"1.2.748971", + "balance":{ + "amount":0, + "asset_id":"1.3.0" + }, + "policy":[ + 1, + { + "vesting_seconds":7776000, + "start_claim":"1970-01-01T00:00:00", + "coin_seconds_earned":"0", + "coin_seconds_earned_last_update":"2018-11-09T11:29:30" + } + ] + }, + { + "id":"1.13.123", + "owner":"1.2.748971", + "balance":{ + "amount":24657392, + "asset_id":"1.3.1" + }, + "policy":[ + 1, + { + "vesting_seconds":7776000, + "start_claim":"1970-01-01T00:00:00", + "coin_seconds_earned":"191735880192000", + "coin_seconds_earned_last_update":"2018-12-04T07:40:00" + } + ] + }, + { + "id":"1.13.237", + "owner":"1.2.748971", + "balance":{ + "amount":1907009, + "asset_id":"1.3.1" + }, + "policy":[ + 1, + { + "vesting_seconds":2592000, + "start_claim":"1970-01-01T00:00:00", + "coin_seconds_earned":"4942967328000", + "coin_seconds_earned_last_update":"2019-01-28T00:40:00" + } + ] + } + ] +} +``` + +## nodo de GXChain relacionado + +### `get_trust_nodes` + +Obtiene los identificadores de cuenta a los que pertenecen todos los nodos de GXChain + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_trust_nodes
API Parameters
+ + +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_trust_nodes", []], + "id": 1 +}' https://node1.gxb.io/rpc +``` +**response:** +```json +{ + "id":1, + "jsonrpc":"2.0", + "result":[ + "1.2.3429", + "1.2.3431", + "1.2.3432", + "1.2.3433", + "1.2.3434", + "1.2.748971", + "1.2.1090296", + "1.2.1090419", + "1.2.1061353", + "1.2.1090653", + "1.2.1090792", + "1.2.1090458", + "1.2.1091083", + "1.2.1092168", + "1.2.1106749" + ] +} +``` +### `get_witness_by_account` + +De acuerdo con 'account_id', se obtiene información de ' nodo de GXChain', incluyendo clave pública de nodo, votos totales, número de bloques perdidos, etc + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_witness_by_account
API Parameters
Parámetro de APIEspecificación de parámetro de API
account_idid de cuenta
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_witness_by_account", ["1.2.748971"]], + "id": 1 +}' https://node1.gxb.io/rpc +``` + +**response:** +```json +{ + "id":1, + "jsonrpc":"2.0", + "result":{ + "id":"1.6.35", + "witness_account":"1.2.748971", // cuenta + "last_aslot":0, + "signing_key":"GXC5YFfb3LtUDnHCu4bTfSMUxoVMz2xwnCbTT99oAdVPCcB2nMKz9", // la clave pública que firma el bloque + "vote_id":"1:56", // witness的vote id + "total_votes":"82099555219", // votos totales + "url":".", + "total_missed":0, // número total de bloques perdidos + "last_confirmed_block_num":0, // Último bloque empaquetado + "is_valid":true // witness状态 + } +} +``` + +### `lookup_vote_ids` + +De acuerdo con vote_id, devuelva la información del nodo de GXchian y el objeto de worker correspondiente + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Namelookup_vote_ids
API Parameters
Parámetro de APIEspecificación de parámetro de API
[vote_id]Matriz, id de votar
+ + +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "lookup_vote_ids", [["1:22", "0:72"]]], + "id": 1 +}' https://node1.gxb.io/rpc +``` + + +## contrato inteligente relacionado + +### `serialize_contract_call_args` +Devuelve una cadena serializada de parámetros de llamada de contrato inteligente en formato hexadecimal +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameserialize_contract_call_args
API Parameters
Parámetro de APIEspecificación de parámetro de API
contract_nameNombre de cuenta del contrato
methodNombre de método
json_argsEl parámetro correspondiente al método de contrato, la cadena key-value json, se puede ser ""
+ + +#### Ejemplo +**request:** +```bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "serialize_contract_call_args", ["gxc-redpacket", "issue", "{\"pubkey\":\"GXC5NEGqM8BTnMm5NT7Vv2Shxh4eg4tk1kfmAUf3EGHtksig5vZdN\", \"number\":10}"]], + "id": 1 +}' https://node1.gxb.io +``` + +**response:** +``` +{"id":1,"jsonrpc":"2.0","result":"35475843354e4547714d3842546e4d6d354e54375676325368786834656734746b316b666d41556633454748746b73696735765a644e0a00000000000000"} +``` + +### `get_table_rows_ex` +interfaz de extensión ' get_table_rows ', proporciona una función de consulta más enriquecida. (los valores predeterminados se utilizan cuando no se pasan los campos de parámetro) + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_table_rows_ex
API Parameters
Parámetro de APIEspecificación de parámetro de API
contract_namenombre de cuenta del contrato
table_namenombre de table
get_table_rows_paramsobjeto de parámetro, puede ser{}
+ +Especificación de parámetro de get_table_rows_params: +``` +lower_bound, el valor mínino del key especificado para la consulta, el valor predeterminado es 0 +upper_bound es el valor máximo del key especificado en la consulta, que por defecto es-1, el entero sin signo más grande +limit,cuando se devuelve la barra de limit especificada de la consulta, la devolución predeterminada es 10 +index_position,el index especificado en la consulta, el valor predeterminado es 1, el primer índice +reverse,el resultado de la consulta se emite en orden inverso según el key, y el valor predeterminado es 0, es decir, salida de pequeño a grande de acuerdo con la clave +get_table_rows_params, todos los parámetros tienen valores predeterminados. Si no necesita cambiar los valores predeterminados, puede dejar de pasarlos en +``` + +#### Ejemplo +**request:** +```bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [0, "get_table_rows_ex", ["gdice", "prizepool", {"lower_bound":0,"upper_bound":-1,"limit":20}]], + "id": 1 +}' https://node1.gxb.io +``` + +**response:** +```json +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "rows": [{ + "pool": { + "amount": "3294138495", + "asset_id": 1 + }, + "totalbet": "30845491144", + "betcount": 38425, + "wincount": 31459, + "minbet": 50000, + "minbank": 10000000, + "investtotalpercent": 2643728290, + "profit": 462683014 + }, { + "pool": { + "amount": 0, + "asset_id": 2 + }, + "totalbet": 0, + "betcount": 0, + "wincount": 0, + "minbet": 1000000, + "minbank": 100000000, + "investtotalpercent": 0, + "profit": 0 + }, { + "pool": { + "amount": "100000000000", + "asset_id": 14 + }, + "totalbet": 0, + "betcount": 0, + "wincount": 0, + "minbet": 10000000, + "minbank": 1000000000, + "investtotalpercent": 100000000, + "profit": 0 + }], + "more": false + } +} +``` + +## La interfaz de gestión de radiodifusión + +### `get_required_fees` + +Dependiendo del contenido de la transacción, obtenga el monto de las tasas requeridas para pagar por la estructura de la transacción + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id0
API Nameget_required_fees
API Parameters
Parámetro de APIEspecificación de parámetro de API
operationsEstructura de transacción
asset_idnúmero de activo
+ + +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc":"2.0", + "method":"call", + "params":[0,"get_required_fees",[[[0,{"fee":{"amount":1000,"asset_id":"1.3.1"},"from":"1.2.955603","to":"1.2.1122226","amount":{"amount":40000,"asset_id":"1.3.1"},"extensions":[]}]],"1.3.1"]], + "id":1 +}' https://node1.gxb.io/rpc +``` + +**response:** +```json +{ + "id":1, + "jsonrpc":"2.0", + "result":[ + { + "amount":1000, + "asset_id":"1.3.1" + } + ] +} +``` + + + +## La interfaz radiodifusión + +### `broadcast_transaction` + +Asincronice la api , difunde una transacción firmada a la red sin esperar el resultado de la ejecución de la transacción + +::: tip Tips +[¿Cómo iniciar transacciones en la cadena?](../advanced/send_transaction.md) +::: + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id2
API Namebroadcast_transaction
API Parameters
Parámetro de APIEspecificación de parámetro de API
signed_trxCuerpo de transacción firmado
+ +#### Ejemplo +**request:** +``` bash +curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [2,"broadcast_transaction",[{"ref_block_num":3698,"ref_block_prefix":1780126622,"expiration":"2018-12-18T10:56:09","operations":[[0,{"fee":{"amount":1000,"asset_id":"1.3.1"},"from":"1.2.17","to":"1.2.6","amount":{"amount":1000000,"asset_id":"1.3.1"},"extensions":[]}]],"extensions":[],"signatures":["204444e23dff4e911e33d4059b36c91f7d4f85022c90ebd3e509f9b2caeb6bca273c8616ebd4f0786ac03b3ef2796a56d754de301e97aff0e43df6f3dfb12d1e62"]}]], + "id": 1 +}' https://node23.gxb.io/rpc +```api + +### `broadcast_transaction_synchronous` + +Sincronice la API, transmita una transacción firmada a la red y espere el resultado de la transacción sincrónicamente, dependiendo de la red y la confirmación de la transacción y otros factores, espere unos 2 segundos + +::: tip Tips +[¿Cómo iniciar transacciones en la cadena?](../advanced/send_transaction.md) +::: + +#### Especificación de parámetro + + + + + + + + + + + + + + + + + + + + + + + + + +
Petición de parámetroPetición de especificación de parámetro
API Id2
API Namebroadcast_transaction_synchronous
API Parameters
Parámetro de APIEspecificación de parámetro de API
signed_trxCuerpo de transacción firmado
+ + +#### Ejemplo +**request:** +``` bash + curl --data '{ + "jsonrpc": "2.0", + "method": "call", + "params": [2,"broadcast_transaction_synchronous",[{"ref_block_num":63524,"ref_block_prefix":3478923091,"expiration":"2019-01-21T07:59:24","operations":[[0,{"fee":{"amount":1000,"asset_id":"1.3.1"},"from":"1.2.22","to":"1.2.18","amount":{"amount":100000,"asset_id":"1.3.1"},"extensions":[]}]],"extensions":[],"signatures":["20165321fabdce0ca561370ba547738be12a33b929b17889845ab9b8c1a4ed2fa04bc555205bc945cf6f0129765a0f1c06265437c111957a4008167ef720c49f71"]}]], + "id": 1 + }' https://node23.gxb.io/rpc +``` + +**response:** +```json +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "id": "8e2a0d30d68a6a34f58cece5b7879d8a8ec123bd", // txid + "block_num": 10680361, + "trx_num": 0, + "trx": { + "ref_block_num": 63524, + "ref_block_prefix": 3478923091, + "expiration": "2019-01-21T07:59:24", + "operations": [ + [0, { + "fee": { + "amount": 1000, + "asset_id": "1.3.1" + }, + "from": "1.2.22", + "to": "1.2.18", + "amount": { + "amount": 100000, + "asset_id": "1.3.1" + }, + "extensions": [] + }] + ], + "extensions": [], + "signatures": ["20165321fabdce0ca561370ba547738be12a33b929b17889845ab9b8c1a4ed2fa04bc555205bc945cf6f0129765a0f1c06265437c111957a4008167ef720c49f71"], + "operation_results": [ + [0, {}] + ] + } + } +} +``` diff --git a/docs/es/guide/clients.md b/docs/es/guide/clients.md new file mode 100644 index 0000000..a7b3d25 --- /dev/null +++ b/docs/es/guide/clients.md @@ -0,0 +1,37 @@ +# Cliente + +## Wallet de linea de comando + + +En [Inicio rápido] (/ zh / guide / # instalación de nodo), presentamos cómo descargar el instalador de nodo. + +La cartera de la línea de comandos `cli_wallet` espera que se complete la sincronización del nodo, inicie la cartera de la línea de comandos en el directorio raíz, haga clic para ver [Tutorial de la cartera de líneas de comandos] (../advanced/cli_wallet.html) + + +## Wallet ligera +| Cliente | Enlaces | Dirección de código abierto | +| :-- | :-- | :-- | +| Web Wallet | [mainnet](https://wallet.gxb.io)/[testnet](https://testnet.wallet.gxchain.org) | [gxchain/gxb-light](https://github.com/gxchain/gxb-light) | +|Cartera móvil (recomendado para usar block City) | [Haga clic para descargar](https://blockcity.gxb.io/download) | [gxchain/gxs-wallet](https://github.com/gxchain/gxs-wallet) | + + +## GXClient + +Para facilitar que el desarrollador llame a la api gxchain en el programa, encapsulamos gxclient e implementamos los siguientes tipos de funciones: + +- [x] [Generar un par de claves público-privadas](https://gxchain.github.io/gxclient-node/api/#chain-api) +- [x] [Obtener información de la cadena](https://gxchain.github.io/gxclient-node/api/#chain-api) +- [x] [Cuenta relacionada](https://gxchain.github.io/gxclient-node/api/#account-api) +- [x] [Activo relacionado](https://gxchain.github.io/gxclient-node/api/#asset-api) +- [x] [Contrato inteligente relacionado](https://gxchain.github.io/gxclient-node/api/#contract-api) + +| Cliente | Enlaces | +| :-- | :-- | +| gxclient-node | [gxchain/gxclient-node](https://github.com/gxchain/gxclient-node) | +| gxclient-ios | [gxchain/gxclient-ios](https://github.com/gxchain/gxclient-ios) | +| gxclient-java | [gxchain/gxclient-java](https://github.com/gxchain/gxclient-java) | +| gxclient-php | [gxchain/gxclient-php](https://github.com/gxchain/gxclient-php) | +| gxclient-c# | [gxchain/gxclient-c#](https://github.com/gxchain/gxclient-csharp) | + + +> Más formas de agregar, bienvenido a subir[Feature Request](https://github.com/gxchain/gxclient-node/issues/new?template=feature_request.md)和[Pull Request](https://github.com/gxchain/gxclient-node)