8000 tools/perl at main · zoobc/tools · GitHub
[go: up one dir, main page]

Skip to content

Latest commit

 

History

History

perl

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Perl

One CPAN-style distribution, ZBC, on Perl 5.16 or newer with 64-bit integers (every stock build of the last decade) and nothing beyond the core modules: SHA-256, SHA-512 and HMAC come from Digest::SHA, JSON from JSON::PP, HTTP from HTTP::Tiny, big numbers from Math::BigInt. SHA3-256, BLAKE2b and Ed25519 are not on CPAN's core list, so they are written here in pure Perl (ZBC::SHA3, ZBC::Blake2b, ZBC::Ed25519). It contains the library (keys, addresses, message signing, the transaction envelope and chain-bound digest, every transaction body, the node client) and bin/zbc-cli.

cd perl
prove -l t                        # every vector in ../spec/vectors through the library and, in-process, the CLI
perl bin/zbc-cli list
perl Makefile.PL && make && make test && make install   # installs ZBC::* and zbc-cli where this perl installs modules

bin/zbc-cli runs from a checkout without installing anything (it adds ../lib to @INC). Math::BigInt::GMP from CPAN, if present, is picked up automatically and makes signing several times faster; the core Math::BigInt::FastCalc signs a transaction in about half a second.

Use the command line

perl bin/zbc-cli send-zbc <64 hex key> ZBC_... 100000000 --api https://<gateway or node>
perl bin/zbc-cli send-zbc - ZBC_... 100000000 --genesis <64 hex> --timestamp 1700000000 --offline    # no node
printf '%s' '{"recipient":"ZBC_...","amount":100000000}' | ZBC_KEY=<64 hex> perl bin/zbc-cli send-zbc --json-input
perl bin/zbc-cli approve-escrow - 0 <escrowed tx hash>
perl bin/zbc-cli sign-message <64 hex key> "text" --genesis <64 hex>  # ZBC-MSG-v2, chain-bound (or --api a node)
perl bin/zbc-cli verify-message ZBC_... "text" <signature> --genesis <64 hex> 
59D8
  # exit 0 valid, 10 not; v1 accepted until 2026-12-01
perl bin/zbc-cli help send-zbc                                    # the fields of one command
perl bin/zbc-cli send-zbc --help                                  # options, environment, exit codes

The contract every command follows is ../spec/cli-contract.md. All 62 transaction types of ../spec/transactions are subcommands; perl script/gen-commands.pl embeds the spec into lib/ZBC/Commands.pm, so a new type in the spec is a regeneration, not new code. The seven types the spec marks custom are in lib/ZBC/Custom.pm. --encrypt seals --message to a ZBC recipient exactly as the C++ tools do (../spec/signing.md 8; X25519, HSalsa20, XSalsa20 and Poly1305 in ZBC::Encryption, core modules only) and zbc-cli decrypt-message <recipient key> <message_hex> opens a sealed field; in the library, seal and open_sealed.

Use the library

use ZBC::Keys qw(key_pair wallet_account);
use ZBC::Message qw(sign_message verify_message);
use ZBC::Transaction qw(sign_transaction send_zbc_body SEND_ZBC);
use ZBC::Address qw(parse_address);
use ZBC::Client;

my $kp = key_pair('<64 hex seed>');                     # $kp->address ZBC_, $kp->node_address ZNK_, $kp->account_bytes
my $acct = wallet_account('<12 or 24 words>', 0, '');   # m/44'/883'/0': $acct->seed, $acct->address, $acct->path

my $s = sign_message($kp->seed, 'hello', $genesis_hash); # ZBC-MSG-v2 (32-byte genesis): {address, digest, signature, genesis_hash, ...} as hex
verify_message($kp->address, 'hello', $s->{signature}, $genesis_hash); # 'ZBC-MSG-v2' (or 'ZBC-MSG-v1' until 2026-12-01), 0 when invalid

my $client = ZBC::Client->new('https://<gateway>', 20);
my $ctx = $client->signing_rule;                        # ZBC::SigningContext (2, genesis) from /api/v1/node/info
my $tx = sign_transaction(SEND_ZBC, time, $kp, parse_address('ZBC_...')->bytes, 5000000, send_zbc_body(100000000), $ctx,
                          ZBC::Escrow->new(approver => 'ZBC_...', commission => 0, timeout => 1800000000, instruction => 'on delivery'));
unpack 'H*', $tx->hash;                                 # the transaction hash
$client->submit_or_die($tx->payload);                   # dies with a ZBC::Error carrying the contract's exit code
$client->status(unpack 'H*', $tx->hash);                # staging | mempool | confirmed | not_found
$client->account($kp->address);                         # balances

Offline signing takes ZBC::SigningContext->of('<genesis hex>') (or 'v1') instead of asking the node. Every body of ../spec/transactions is available through ZBC::Body::build_body($def, \%params, $kp) with ZBC::Commands::by_name('issue-token') and friends; multisig_address, proof_of_ownership (signed by the node key) and the custom builders in ZBC::Custom are public. Strings are bytes throughout: pass UTF-8 encoded text, as the command line does.

Layout

lib/ZBC/        SHA3, Blake2b, Ed25519, Encryption, Encoding, Bip39Words, Error, ExitCode, Address, Keys, Message, Transaction,
                Commands (generated), Body, Custom, Client, CLI;  lib/ZBC.pm loads them all
bin/zbc-cli     the command line;  script/gen-commands.pl  writes lib/ZBC/Commands.pm from ../spec/transactions
t/vectors.t     the vector suite (prove -l t)
Makefile.PL     ExtUtils::MakeMaker: perl Makefile.PL && make test && make install

ZBC::Ed25519 is a straightforward RFC 8032 implementation on Math::BigInt; it is not constant time. Keep seeds on machines you trust, as with any scripting-language signer.

0