¿Con qué denominación debo emitir mi token ERC20?

Siguiendo el tutorial "Crear una criptomoneda" en ethereum.org, terminé con la siguiente función (reducida):

function () payable {
    if (msg.value == 0) { return; }
    uint256 tokens = msg.value * 100;

    owner.transfer(msg.value);
    balance[msg.sender] += tokens;
}

Debido a que msg.valueestá en wei, el envío de 0.01 ETH daría como resultado la recepción de tokens 1e18. Quiero emitir cantidades más pequeñas de tokens, idealmente, 1 ERC20 por 0.01 ETH como lo hace el tutorial, pero ¿eso no introduciría errores de precisión de coma flotante?

Respuestas (1)

La solidez no puede hacer punto flotante. Es por eso que almacenamos y realizamos transacciones con la unidad más pequeña disponible por sus decimales. Son la única unidad que realmente existe, es decir: Wei en Éter. "1 Ether" es una fantasía. Simplemente significa 1000000000000000000 (o 1e18) Wei.

Las fichas de éter tienen 18 decimales. Digamos que usamos 6 decimales en su lugar y desea comprar diez tokens, a un valor de 1 ERC20 por 0.01 ETH.

uint public decimals = 6;

Por eso, nuestro multiplicador es 1e6, o 1000000. Seis decimales. El de Ethereum sería 1e18.

uint MULTIPLIER = 1000000; // six decimals to the left
uint price = 10000000000000000; // 1e16 wei per token;

Si envía 0.1 ETH, está enviando 1e17. El precio de un token es 1e16.

uint amount = msg.value; // msg.value is 1e17
uint tokens = amount / price * MULTIPLIER; // or 1e17 / 1e16 * 1e6 // amount / price will be 10. then 10 * 1000000 gets you 10,000,000, a.k.a Ten of your ERC20 tokens valued at 1,000,000 "erc20 wei" each.

Fichas es la cantidad de fichas, con seis decimales, que usaría en token.transfer(address to, uint amount)el método como la cantidad.

Siempre que muestre esto al usuario final, debe dividir el resultado por el multiplicador para obtener la cantidad real de tokens, porque estamos almacenando en ERC20 "wei".

Si agrega el token a Metamask o lo visita en Etherscan, podrá extraer la variable "decimales" y hacer los cálculos para mostrarlo con precisión. Así es como todos los tokens de Ethereum muestran el valor correcto. Las billeteras son inteligentes y conocen el estándar ERC20 y buscan una variable llamada decimales.

Mucho de esto es pseudocódigo y estoy seguro de que las matemáticas se pueden romper, pero la idea general está ahí. Es posible que desee verificar que la oferta mínima sea 1e16 antes de procesar, de lo contrario, terminará con errores de punto flotante (es decir, si alguien envió 1e15 wei y lo dividió por 1e16).

editar: Además, donde dices que Because msg.value is in wei, sending 0.01 ETH, would result in receiving 1e18 tokenses incorrecto, 1 ETH = 1e18 wei. 0.01 eth daría como resultado 1e16 wei.