​
Zen Protocol is a multi-token blockchain, any contract can issue any number of tokens. Each token (called an asset) is represented by the contract identifier and optional sub type (of 32 bytes).
Zen assets are represented by one byte of the value 0 (zero).
Each asset also has a string representation, which is being used in the UI and API. Zen tokens are represented by the string 00 (zero zero).
Unlike bitcoin, when sending an asset we have to specify which asset are we spending. Therefore the API always requires an additional asset parameter on the wallet/send
and wallet/execute
API calls.
The Zen-Node exposes an API for accepting payments.
For each payment we generate a new unique address and provide it to the end-user. Then periodically check the amount received for each address and save it. When the amount for address changed between calls you know the user made a payment. You can also specify the minimum confirmations required to consider a payment as complete.
All the assets belong to the wallet and can be spent by the wallet/send
API call.
You first have to create a wallet, either through the UI or via the zen-cli
. The private key is encrypted, however it is still on the hot zen-node machine, therefore this solution should be treated as a hot wallet.
​
{"address": "tzn1q7gye0nkgxuwal949y4ke94mwfwsf7eaafy7p5tkdcr6ujuyglqwsnjv2gt","index": 0}
[{"address": "tzn1q7huplz5q5w7w9234a43hk4llyaegedq6dlfgm7mfp5w3em6s3uus4hwj7q","asset": "00","amount": 9497378334165913},{"address": "tzn1q7huplz5q5w7w9234a43hk4llyaegedq6dlfgm7mfp5w3em6s3uus4hwj7q","asset": "000000006a26b38c2875d1379405bb7d140078ccffb560aff839a3d846850e99ab3d9de84265617200000000000000000000000000000000000000000000000000000000","amount": 199999994},{"address": "tzn1qlvm8ey4m5mj6ak3an39qdfzf7yx4uz59flzlant6jp0gzld48egsj433m6","asset": "00","amount": 1855040761794}]
​
You can also use cold wallet for the payment processing.
You will have to use zen.js library for the process.
Generate an extended private key on a secure computer and import the extended public key.
import {Mnemonic, ExtendedKey} from '@zen/zenjs'​const mnemonic = Mnemonic.generateMnemonic(24); // Generate onceconsole.log('mnemonic phrase', mnemonic);​const publicKey = ExtendedKey.fromMnemonic(mnemonic).neutered();​console.log('Extended Public Key', publicKey.toString());
On a hot machine generate a unique address by deriving the key with a unique index. Save the index to later sign the transaction on the secure computer.
import {ExtendedKey} from '@zen/zenjs'import {post} from 'axios'​const publicKey = ExtendedKey.fromString(encodedString);const address = publicKey.derive(uniqueIndex).toAddress();​// import the address to zen nodepost('http://127.0.0.1/:31567/wallet/importwatchonlyaddress',address,{ headers: { 'Content-Type': 'application/json' }});
Share the address with the user and track the address for income payments the same as for the hot wallet, by calling wallet/receivedbyaddress
To make a payment you will to get the outputs from the zen-node and assemble the transaction on the secure computer. Retrieve the available outputs by calling wallet/addressoutputs
for each address.
Example of assembling and publishing transaction:
import {TransactionBuilder,ExtendedKey} from '@zen/zenjs'import {post} from 'axios'​const tb = new TransactionBuilder('main');​// Get the private key by matching the unique index for the input addressconst privateKey = ExtendedKey.fromMnemonic(mnemonic).derive(inputAddressIndex).getPrivateKey();​// An example input, use one you retrieved by calling `wallet/addressoutputs`tb.addInput('0000000000000000000000000000000000000000000000000000000000000000',0, privateKey);​// Address, amount and token (Zen)tb.addOutput('tp1qfyplhxql09lvvg53dxg7t77tkkxhsp3l6q8xjjpj85hvqlw0ttqswjdapx', 100, '00');​const tx = tb.sign();​// You can take the hex to an hot computerconst hex = tx.toHex();​// Transaction is ready to be publishedpost('http://127.0.0.1/:31567/blockchain/publishpublishtransaction',hex,{ headers: { 'Content-Type': 'application/json' }});​
​