Claves y tipos de cuenta
Una cuenta de ZooBC se controla con una firma, nunca con un nombre de usuario, una contraseña o una clave de API. Qué firma depende del tipo de la cuenta. Además de sus cuentas nativas Ed25519, ZooBC acepta cuentas cuyas direcciones se escriben como las escriben Bitcoin, Ethereum, Solana, Polkadot, Cardano, Ripple, Tron y Tezos, y comprueba sus firmas con el esquema propio de cada cadena. Por tanto, una clave de Bitcoin o de Ethereum puede controlar una cuenta de ZooBC en la misma dirección que tiene en su cadena de origen. Esa cuenta es independiente, está en el propio libro contable de ZooBC y contiene ZBC.
Una dirección es un tipo y una carga
Una dirección es un número de tipo de 4 bytes (little-endian) seguido de una carga cuyo significado y longitud decide el tipo (cuentas y direcciones). Para una cuenta nativa, la carga es la propia clave pública Ed25519; para una cuenta de Ethereum, son los últimos 20 bytes del hash Keccak-256 de la clave; para una cuenta P2PKH de Bitcoin, es el HASH160 de la clave.
| Tipo | Cuenta | Se escribe | Puede firmar |
|---|---|---|---|
| 0 | ZooBC, Ed25519 | ZBC_… | sí |
| 1 | Bitcoin heredado (HASH160) | — | sí |
| 2 | Empty («sin destinatario») | — | no |
| 3 | Estonia eID (reservado) | — | no |
| 4 | Ethereum | 0x… | sí |
| 5 | Bitcoin P2PKH | 1… | sí |
| 6 | Bitcoin P2SH, verificado como P2SH-P2WPKH | 3… | sí |
| 7 | Bitcoin P2WPKH | bc1q…, 42 caracteres | sí |
| 8 | Bitcoin P2WSH (script) | bc1q…, 62 caracteres | no |
| 9 | Bitcoin Taproot | bc1p… | sí |
| 10 | Objeto de dataset | ZBS_… | no |
| 11 | Solana | como en Solana | sí |
| 12 | Polkadot | como en Polkadot | sí |
| 13 | Cardano | addr1… | sí |
| 14 | Ripple | r… | sí |
| 15 | Tron | T… | sí |
| 16 | Tezos | tz1… | sí |
Las direcciones sin clave tampoco pueden firmar: los fondos del protocolo, los grupos de cuentas y las cuentas multifirma no tienen clave, así que sus fondos solo se mueven según las reglas del protocolo.
La forma de texto nativa es ZBC_ seguido de 56 caracteres base32 en siete grupos de ocho: la clave de 32 bytes más una suma de verificación SHA3-256 de 3 bytes que cubre también el prefijo. Al leerla se ignoran los separadores, los espacios y las mayúsculas o minúsculas. La misma clave de 32 bytes también puede escribirse como clave de nodo (ZNK_), clave de relay (ZBR_) o clave de pasarela (ZBG_).
Un mismo resumen para todos los esquemas
Todos los tipos de cuenta firman el mismo resumen vinculado a la cadena:
digest = SHA3-256("ZBC-TX" ‖ genesis hash ‖ unsigned transaction bytes)
Solo se acepta este resumen; una firma sobre los bytes desnudos se rechaza. El hash del génesis ata cada firma a una sola cadena (firmas vinculadas a la cadena). Algunos esquemas aplican un hash más al resumen, como exige su cadena de origen.
Los esquemas
- Ed25519 sobre el resumen de 32 bytes, para ZooBC (tipo 0) y Solana (11). Cardano (13) y Tezos (16) también firman con Ed25519, pero sus direcciones son hashes, así que el campo de firma lleva también la clave: 98 bytes formados por una longitud de 2 bytes, la clave y la firma. La clave se vincula a la dirección mediante BLAKE2b-28 (Cardano) o BLAKE2b-20 (Tezos).
- ECDSA secp256k1, al estilo de Bitcoin, para los tipos 1, 5, 6 y 7 y para Ripple (14). El campo de firma lleva la clave: una longitud de 2 bytes, una clave de 33 o 65 bytes y después la firma de 64 bytes (r y s). El HASH160 de la clave debe coincidir con la dirección, el mensaje firmado es el doble SHA-256 del resumen y solo se aceptan firmas low-s.
- ECDSA secp256k1, al estilo de Ethereum, para Ethereum (4) y Tron (15): una firma de 65 bytes (r, s y v) sobre el hash Keccak-256 del resumen. La clave se recupera a partir de la firma y se compara su dirección; las firmas high-s se rechazan.
- Schnorr BIP-340 para Taproot (9), con la clave de salida x-only; la billetera aplica el ajuste (tweak) de Taproot.
- sr25519 para Polkadot (12), bajo el contexto de firma "substrate".
Las cuentas Taproot también pueden recibir ZBC mediante SendZBC en todas las cadenas desde el génesis.
Verificar una clave que no está guardada
Una dirección al estilo de Ethereum es solo un hash de 20 bytes; la clave pública no está guardada en ninguna parte de la cadena. Las firmas de Ethereum son recuperables: a partir del mensaje firmado y de la firma de 65 bytes, cualquiera puede calcular la única clave pública que la produjo. El nodo hace exactamente eso, toma los últimos 20 bytes del hash Keccak-256 de la clave recuperada y solo acepta la firma si coinciden con la dirección. Como se rechazan las firmas high-s, una firma no puede alterarse para obtener una segunda forma válida. No hace falta ningún paso de registro ni ninguna consulta externa, y las cuentas 0x pueden enviar con la misma libertad con la que reciben.
Transacciones de otras cadenas transportadas dentro
Un remitente con una cuenta de otra cadena también puede poner una transacción nativa de su cadena de origen en el campo de mensaje de una transacción de ZooBC. Por esta vía, el nodo comprueba la transacción de la otra cadena y su firma en lugar del resumen de ZooBC:
- Ethereum (tipo 4): una transacción EIP-1559, EIP-2930 o heredada (EIP-155) con una lista de acceso vacía. Su firmante recuperado debe ser el remitente, su
toel destinatario, y su valor en wei dividido entre 10^10 el importe (MetaMask y el acceso al estilo de Ethereum). - Solana (tipo 11): una transferencia del System program cuyos lamports son iguales al importe.
- Bitcoin (tipos 7 y 5): una entrada, una o dos salidas y una comisión de minero de cero; la salida 0 paga al destinatario y la salida 1, si existe, devuelve el cambio al remitente.
Un mensaje así puede tener hasta 4096 bytes, y la transacción no puede llevar un pago de supervivencia (sobre de la transacción).
Derivar claves nativas
Una clave nativa se deriva de una frase de recuperación BIP-39: PBKDF2-HMAC-SHA512 con 2048 rondas, y después SLIP-0010 Ed25519 según m/44'/883'/n', con todos los pasos endurecidos. 883 es el tipo de moneda de ZooBC.