es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Generación de firma EIP-721 fuera de la cadena utilizando Ruby y validación en la cadena utilizando Solidity.

Estoy trabajando en un proyecto en el que necesito enviar tokens a nuestros usuarios a través de Airdrop. En el backend se identifica la cantidad de tokens enviados a una dirección. Para validar la dirección y la cantidad de tokens al reclamar, necesito tener alguna validación en su lugar. Similar a cómo se hace en estos dos contratos:
https://etherscan.io/address/0xedfccec033521cbfb3a4aaa86824aaa6747ea35f#code
https://etherscan.io/address/0x3b484b82567a09e2588a13d54d032153f0c0aee0#code

La pregunta es cómo genero las firmas EIP-712 en el backend de Ruby on Rails, de manera que sean verificables en el contrato inteligente.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para generar firmas EIP-712 en un backend de Ruby on Rails, se puede utilizar la gema ethers-ruby, la cual proporciona una forma de crear y verificar firmas EIP-712.

    Aquí tienes una implementación de ejemplo:

    1. Instala la gema ethers-ruby:
    gem 'ethers-ruby'
    
    1. Requiere las librerías necesarias:
    require 'eth'
    require 'eth/signer'
    require 'eth/abi/encoder'
    
    1. Define el separador de dominio y el esquema del mensaje:
    domain_separator = {
      name: 'Nombre del Proyecto',
      version: '1',
      chainId: 1,
      verifyingContract: '0x1234...'
    }
    
    message_schema = {
      'address' => 'address',
      'amount' => 'uint256',
      'nonce' => 'uint256'
    }
    
    1. Define una función para generar el hash EIP-712:
    def generate_eip712_hash(domain_separator, message_schema, data)
      Eth::Utils.keccak256(
        [
          '0x1901', # Encabezado EIP-191
          Eth::Utils.keccak256(
            Eth::ABI::Encoder.encode(
              [
                {
                  type: 'bytes32',
                  name: 'DomainSeparator'
                },
                {
                  type: 'bytes32',
                  name: 'Message'
                }
              ],
              [
                Eth::Utils.keccak256(
                  Eth::ABI::Encoder.encode(
                    [
                      {
                        type: 'string',
                        name: 'name'
                      },
                      {
                        type: 'string',
                        name: 'version'
                      },
                      {
                        type: 'uint256',
                        name: 'chainId'
                      },
                      {
                        type: 'address',
                        name: 'verifyingContract'
                      }
                    ],
                    [
                      domain_separator[:name],
                      domain_separator[:version],
                      domain_separator[:chainId],
                      domain_separator[:verifyingContract]
                    ]
                  )
                ),
                Eth::Utils.keccak256(
                  Eth::ABI::Encoder.encode(
                    Eth::ABI::Types::Utils.camelize(message_schema),
                    data
                  )
                )
              ]
            )
          )
        ]
      )
    end
    
    1. Define una función para firmar el hash EIP-712:
    def sign_eip712_hash(private_key, domain_separator, message_schema, data)
      signer = Eth::Signer.new(private_key)
      eip712_hash = generate_eip712_hash(domain_separator, message_schema, data)
      signature = signer.sign(eip712_hash)
      {
        v: signature.v,
        r: signature.r,
        s: signature.s
      }
    end
    
    1. Llama a la función sign_eip712_hash con la clave privada, el separador de dominio, el esquema del mensaje y los datos:
    private_key = Eth::Key.new(priv: '...')
    data = {
      'address' => '0x1234...',
      'amount' => 100,
      'nonce' => 0
    }
    signature = sign_eip712_hash(private_key, domain_separator, message_schema, data)
    

    El objeto signature resultante se puede pasar como argumento signature a la función claim del contrato inteligente para su validación.

Comments are closed.