Saltar al contenido principal

06 · Configuración de entornos y aceptación

Parámetros de red, activo de demostración, ejemplos de consulta y lista de aceptación para los entornos públicos.

6.1 Entornos​

ElementoPruebasDemostración mainnet
UsoDesarrollo, integración, aceptaciónVerificación de capacidades
RedBohr TestnetBOT Mainnet
EstadoDisponibleSuite desplegada
Chain ID968677
RPChttps://rpc.bohr.lifehttps://rpc.botchain.ai
Exploradorhttps://scan.bohr.lifehttps://scan.botchain.ai
GasBOT de pruebaBOT

Direcciones, saldos, identidades y Claims son independientes.

6.2 Estructura recomendada​

type RwaEnvironment = {
chainId: number;
rpcUrl: string;
explorerUrl: string;
contracts: {
token: string;
identityRegistry: string;
onchainIdGateway?: string;
idFactory?: string;
claimIssuer?: string;
};
};
const rwaTestnet = {
chainId: 968,
rpcUrl: 'https://rpc.bohr.life',
explorerUrl: 'https://scan.bohr.life',
contracts: {
token: '0xA7aEb5cc99C558E7A237aA1B3483e71E59e66036',
identityRegistry: '0x5C3f759a7Fe22331750E6CA3293a96C34daE3417',
onchainIdGateway: '0xb62261a7193B6F37A5c6A2c242aD542C840d6f5a',
idFactory: '0xEa3216f557B6598F53fCcd146E63912c4c1be02C',
claimIssuer: '0xEa7E7c89F56f167E12570E15d648460104510d47',
},
};
const rwaMainnet = {
chainId: 677,
rpcUrl: 'https://rpc.botchain.ai',
explorerUrl: 'https://scan.botchain.ai',
contracts: {
token: '0x58F96a44594C9C5C8DE282Eeb75208B5f11C0c36',
identityRegistry: '0xe0b6FbEa0a9af21ddd455D6cA776478cAbe7c141',
onchainIdGateway: '0xFCF1E45f42aAa5CccA0A035f7a946BC8Fd55Fac6',
idFactory: '0xE97099950DFe98535927a650658c0E964c8d6f67',
claimIssuer: '0xD40b0c8dC960755C2586601Ff505F036FfE9BF59',
},
};

No retroceda automáticamente a testnet si mainnet falta o falla. JSON mainnet.

6.3 Activo público​

ElementoValor
Nombre / símbolo / decimalesProject Real World Asset / PRWA / 6
TopicKYC_APPROVED
Valor Topic7151541257903274562366177585585886223835338030660388602590463654390840817671
Scheme1
Países156, 702

6.3.1 Bohr Testnet​

ContratoDirección
Token0xA7aEb5cc99C558E7A237aA1B3483e71E59e66036
IdentityRegistry0x5C3f759a7Fe22331750E6CA3293a96C34daE3417
IdentityRegistryStorage0x3fae839c1642BDcFBE94b5A8088a56F8fC787707
ClaimTopicsRegistry0x042a938B2cE1e1AdF2b4101D9730722d5c75F773
TrustedIssuersRegistry0x2323413Abd0BF763ed2f3bE9c319A7a05985C2ff
ModularCompliance0x3aa6A97b6d61039A65C5AEf5649523732379aE9C
Token ONCHAINID0x7528D8d23fE511c658564E1cB346ca7D9B72788d
CompartidoDirección
ONCHAINID Gateway0xb62261a7193B6F37A5c6A2c242aD542C840d6f5a
IdFactory0xEa3216f557B6598F53fCcd146E63912c4c1be02C
ClaimIssuer0xEa7E7c89F56f167E12570E15d648460104510d47
TREXGateway0xf73CB3A2830bef113Be01CD5eE5C99d21e43107B
Country Allowlist0x5Da275CcC6eAb8bd43800AB54B9c8Ec48129aB30

6.3.2 BOT Mainnet​

ContratoDirección
Token0x58F96a44594C9C5C8DE282Eeb75208B5f11C0c36
IdentityRegistry0xe0b6FbEa0a9af21ddd455D6cA776478cAbe7c141
IdentityRegistryStorage0x344D8266058FcE40D8229F8eF118da5ee6f88c54
ClaimTopicsRegistry0x7778b431b73F57722cBa7D6205F45858D789ACB1
TrustedIssuersRegistry0xC3216525E30E0369B49d75105b3591b647595d63
ModularCompliance0xE0444e1374d5ca5EdF3DAb0bEB54165c8D1968a4
Token ONCHAINID0x651b1Ad7F96A16228e41cDf6c2eb2282C267dE6B
CompartidoDirección
ONCHAINID Gateway0xFCF1E45f42aAa5CccA0A035f7a946BC8Fd55Fac6
IdFactory0xE97099950DFe98535927a650658c0E964c8d6f67
ClaimIssuer0xD40b0c8dC960755C2586601Ff505F036FfE9BF59
TREX ImplementationAuthority0x658B369FFfE2474310224c6DAe2f320A27A76D2E
ONCHAINID ImplementationAuthority0xA5aeF4767C10fE47d1097b65Da55357B29bbbfF6
IAFactory0x394f0720F519e25d63065690d8565018404b69E8
TREXFactory0xCdc6C38438DEd768028EecFd50a8aAf3ad755a92
TREXGateway0x7a8bea060430D7A6B5ac816137733570425Bb777
Country Allowlist0x8AD1cdF24Bf38E9b649294fb01e2A9E83F0E19E5

Country Allowlist no ha completado una auditoría de producción. La Suite es solo de demostración técnica y no debe portar activos reales.

JSON testnet · JSON mainnet

6.4 Carteras públicas​

EjemploCarteraONCHAINID testnetPaísVerificado
Alice0xb450970Eece71044acF7cB7f53Ee51e3BC2EA9220xfAB41B1DfD098F439D75cEA0cb48f70B46052544156true
Bob0xfc996C5378fe0cd03Fd4296075abc07B16b2B12F0xd3b816e7494e918297E3553d65488a7E0682C6A3702true
Cathy0x2b981b025397AE1AFca6f8DC7A2f5C7A868dEe780xb7522A6649a20A0820E292D8D0f35aB792812011156true

No se proporcionan claves privadas. Para escritura, use una cartera propia.

La Suite de demostración de capacidades más reciente de BOT Mainnet solo ha completado el despliegue y la verificación del código fuente. Aún no se han creado los ONCHAINID de las carteras públicas ni se han emitido Claims o realizado registros en IdentityRegistry. Por ello, actualmente no se publican carteras de ejemplo de mainnet con isVerified == true; esta sección se completará después de la inicialización operativa independiente y la aceptación onchain.

Para negativos, use una cartera propia no registrada: contains == false, isVerified == false.

6.5 Validar red y contrato​

Ejemplos con ethers.js v5:

const { ethers } = require('ethers');
const provider = new ethers.providers.JsonRpcProvider('https://rpc.bohr.life');
const network = await provider.getNetwork();
if (network.chainId !== 968) {
throw new Error(`Wrong network: expected 968, got ${network.chainId}`);
}
const TOKEN = '0xA7aEb5cc99C558E7A237aA1B3483e71E59e66036';
const IR = '0x5C3f759a7Fe22331750E6CA3293a96C34daE3417';
if (await provider.getCode(TOKEN) === '0x') {
throw new Error('Token contract not found on current network');
}

Valide Chain ID antes de escribir.

6.6 Leer el activo​

const token = new ethers.Contract(TOKEN, [
'function name() view returns (string)',
'function symbol() view returns (string)',
'function decimals() view returns (uint8)',
'function totalSupply() view returns (uint256)',
'function identityRegistry() view returns (address)',
'function compliance() view returns (address)',
'function paused() view returns (bool)',
], provider);

const [name, symbol, decimals, supply, registry, compliance, paused] =
await Promise.all([
token.name(), token.symbol(), token.decimals(), token.totalSupply(),
token.identityRegistry(), token.compliance(), token.paused(),
]);
console.log({name, symbol, decimals,
totalSupply: ethers.utils.formatUnits(supply, decimals),
registry, compliance, paused});

Acepte cuando nombre/símbolo, decimals, IR y MC coincidan con la publicación.

6.7 Saldo y elegibilidad​

const wallet = '0xb450970Eece71044acF7cB7f53Ee51e3BC2EA922';
const ir = new ethers.Contract(IR, [
'function contains(address) view returns (bool)',
'function isVerified(address) view returns (bool)',
'function identity(address) view returns (address)',
'function investorCountry(address) view returns (uint16)',
], provider);
const [rawBalance, contains, verified, identity, country] =
await Promise.all([
token.balanceOf(wallet), ir.contains(wallet), ir.isVerified(wallet),
ir.identity(wallet), ir.investorCountry(wallet),
]);
console.log({balance: ethers.utils.formatUnits(rawBalance, decimals),
contains, verified, identity, country});

Las muestras deben devolver contains y verified verdaderos.

6.8 Eventos​

const latest = await provider.getBlockNumber();
const logs = await token.queryFilter(
token.filters.Transfer(), Math.max(0, latest - 5000), latest
);
for (const log of logs) {
console.log({
txHash: log.transactionHash, blockNumber: log.blockNumber,
from: log.args.from, to: log.args.to,
value: ethers.utils.formatUnits(log.args.value, decimals),
});
}

Consulte por tramos y checkpoints.

6.9 Escrituras​

OperaciónFirmanteRequisito
Crear ONCHAINIDCartera inversorGas
addClaimGestor ONCHAINIDFirma Claim
registerIdentityIR AgentSoporte del emisor
mint / burnToken AgentSoporte del emisor
transferTitularElegibilidad y reglas

Nunca transfiera claves privadas. Los PRWA públicos están pausados; transfer solo funciona después de unpause().

const recipient = '0xfc996C5378fe0cd03Fd4296075abc07B16b2B12F';
const senderAddress = await signer.getAddress();
const amount = ethers.utils.parseUnits('10', decimals);
if (await token.paused()) throw new Error('Token transfers are currently paused');
if (!await ir.isVerified(recipient)) throw new Error('Recipient is not verified');
const compliance = new ethers.Contract(
await token.compliance(),
['function canTransfer(address,address,uint256) view returns (bool)'],
provider
);
if (!await compliance.canTransfer(senderAddress, recipient, amount)) {
throw new Error('Transfer rejected by compliance rules');
}
const receipt = await (await token.connect(signer).transfer(recipient, amount)).wait();
console.log(receipt.transactionHash);
await (await token.connect(ownerSigner).approve(spender, amount)).wait();
await (await token.connect(spenderSigner)
.transferFrom(ownerAddress, recipient, amount)).wait();

El recibo determina el resultado final.

6.10 Lista de aceptación​

Entorno​

  • Configuración independiente;
  • Chain ID estricto;
  • Datos de publicación oficial;
  • Sin fallback de mainnet a testnet.

Contratos y transacciones​

  • Nombre, símbolo, decimals, IR y MC correctos;
  • Bytecode y ABI correctos;
  • parseUnits / formatUnits;
  • Estados enviado/confirmado/fallido;
  • Sin actualización final tras fallo ni mint/burn duplicado.

Identidad y seguridad​

  • IR del activo correcto;
  • Diferenciar contains e isVerified;
  • KYC claro fuera de cadena;
  • Mensajes de rechazo comprensibles;
  • Sin claves en frontend/repositorio/logs;
  • Firmas controladas, proxies y avisos de seguridad.

6.11 Diagnóstico​

1. Chain ID
2. RPC
3. Bytecode
4. Token.name / decimals / identityRegistry
5. balance / paused / isFrozen
6. contains / isVerified
7. compliance.canTransfer
8. Rol firmante
9. callStatic / estimateGas
10. Recibo y eventos

Si testnet funciona y mainnet falla, compare red, direcciones, cualificaciones y reglas.

Anterior: 05 · Interfaces y eventos · Inicio