Por Albert Palau

En los desarrollos open source descentralizados, es muy importante definir estándares para aunar y focalizar esfuerzos en la misma dirección. ¿Quién hubiera previsto la importancia que han tenido las ICOs en la tecnología blockchain? Parte del éxito ha sido gracias a la definición del estándar ERC20, que ha permitido que todo el ecosistema cree soluciones y proyectos a su alrededor.

Actualmente, existen muchas propuestas de mejora sobre el ERC20 que se están debatiendo y valorando. En este artículo hablaremos sobre ERC827 por tres razones, principalmente: la ejecución de código de forma transaccional en el envío (y approve) de tokens por parte de una EOA (dirección de usuario o Externally Owned Account), porque un framework de referencia como OpenZeppelin ofrece una implementación lista para ser
usada de forma segura y, por último, porque es totalmente compatible con la interfaz ERC20, por lo que todas las herramientas que soportan ERC20 soportan de facto ERC827.

La definición de la interfaz se define en https://gi- thub.com/ethereum/EIPs/issues/827. Y la implementación de OpenZeppelin la podéis encontrar en http://en https://github.com/OpenZeppelin/zeppelin-solidity/

La motivación principal es clara: el estándar ERC20 únicamente define un cambio de balance (valor) entre usuarios de un token. Sin embargo, al igual que podemos hacer en transacciones comunes de Ethereum, la red nos permite enviar datos para ejecutar código en la misma transferencia.

El hecho de poder ejecutar código arbitrario nos abre un amplio abanico de posibilidades. Por ejemplo, pagar en tokens por la ejecución de cierta lógica de negocio.

Supongamos el siguiente ejemplo: hemos creado una comunidad que utiliza el token ACH, de AChain, y para poder entrar en las reuniones secretas, necesitas ejecutar código de un smart contract para que te dé acceso. Esta pieza de código requerirá el pago de una cierta cantidad de ACH, por lo que validará si tienes suficientes fondos y, si tienes suficiente, te cobrará y te dará acceso. Si hiciéramos esta operación utilizando un ERC20, tendríamos que enviar una transacción de approve para que el contrato de AChain pueda transferir, de nuestros tokens, cierta cantidad como pago. Después, realizaríamos otra transacción al contrato de AChain para ejecutar la lógica de negocio y, como previamente le hemos dado permisos para transferir fondos de nuestra parte, se cobrará y nos dejará ejecutar la función.

Si hiciéramos esto con ERC827, podríamos hacerlo todo en la misma transacción. Enviaríamos una transacción de approve y adjuntaríamos, en el campo data, la llamada a la función de AChain. De esta manera, en la misma transacción, estaríamos ejecutando, de forma cronológica, las siguientes operaciones: approve (token)-allowance(AChain)-transferFrom(AChain).

Veamos un ejemplo práctico:

En el enlace https://github.com/albpal/ERC827-copy-paste/blob/master/ERC827-AChain.sol he dejado la creación del siguiente token ERC827:

contract AChain is ERC827Token {
string public constant name = “AChain”; // solium-disable-line uppercase
string public constant symbol = “ACH”; // solium-disable-line uppercase
uint8 public constant decimals = 0; // solium-disable-line uppercase
uint256 public constant INITIAL_SUPPLY = 100 * (10 ** uint256(decimals));
/**
* @dev Constructor that gives msg.sender all of existing tokens.
*/
function AChain() public {
totalSupply_ = INITIAL_SUPPLY;
balances[msg.sender] = INITIAL_SUPPLY;
Transfer(0x0, msg.sender, INITIAL_SUPPLY);

Listo para copiar y pegar en Remix y poder hacer vuestras pruebas.

Una vez tenemos nuestro token de la comunidad, crearemos el smart contract que requerirá un pago en ACH para ejecutar sus funciones:

contract AChainLogic{string public doorState;
function AChainLogic() public { doorState = “closed”;}
function PayToExecute() public returns (bool) {
ERC20 tokenContract = ERC20(msg.sender);
uint256 allowedValue = tokenContract.allowance(tx.origin, this);
require(allowedValue >= 50);
tokenContract.transferFrom(tx.origin, this, 50);
return openTheDoor();
}
function openTheDoor() private returns (bool)
{
doorState = “opened”;
return true;
}
}

El código completo para copiar y pegar lo tenéis en: https://github.com/albpal/ERC827-copy-paste/blob/ master/AChain-logic.sol.

En mi caso, las direcciones de ambos contratos, en Ropsten, son:

AChainLogic: 0xe98e12643A4D8818e46219794cd283e7eA2525B2

AChain (token): 0xCA740684625c94DA14b361114eF34C083F87143D

Podemos ver el balance de nuestro nuevo token AChain en MetaMask gracias a que es compatible con ERC20:

Si consultamos el estado de la puerta, veremos que está cerrada:
achain.doorState(function(err,res){console.log(err);console.log(res)})
closed

Para abrirla, deberemos pagar en ACH de la siguiente manera:
function_sign=web3.sha3(“PayToExecute()”).substr(2,8)
achain_token.approve(“0xe98e12643A4D8818e46219794cd283e7eA2525B2”,50, function_sign, function(){})

De tal forma que ahora la variable doorState pasará de closed a opened:
achain.doorState(function(err,res){console.log(err);console.log(res)}) opened

Y, si consultamos el balance del token ACH para la dirección del smart contract, veremos que se ha incrementado en 50:
achain_token.balanceOf(“0xe98e12643A4D8818e46219794cd283e7eA2525B2”, function(err,res){console.log(res)})

Como acabamos de comprobar, el estándar ERC827 nos permite ejecutar código en la misma transacción de pago desde una dirección gestionada por un usuario (no un smart contract) haciendo que sea más fácil, eficiente y, lo mejor de todo, totalmente compatible con todas las herramientas de gestión de tokens ERC20.

¿Qué nuevos estándares surgirán? ¿Qué nueva revolución, similar a las ICOs, aparecerá? Seguramente, este tipo de plataformas dará mucho que hablar en un futuro no muy lejano.

Atención: Recientemente se han detectado incompatibilidades entre el ERC827 cuando el destino del approve o transfer son otros smart contracts ERC223 o ERC777. Por este motivo, se recomienda seguir de cerca esta discusión y los comunicados oficiales de OpenZeppelin antes de su uso.