KLYNTAR Docs
TwitterDiscordSiteGitHub
  • Klyntar project intro
  • Project litepaper and main features
    • About project
    • Unique architecture - take the best from L1 and L2 chains
    • Multilevel sharding and modularity
    • Multistaking - native liquid staking, multichain multiasset staking and much more!
    • Checkpoints mechanism
    • Advanced cryptography - zk, mpc, fhe, post-quantum and much more!
    • Virtual machines - EVM, WASM, containers and much more!
    • Parallelization
    • Abstractions - for account, storage and chain
    • RWX - codeless smart contracts for real world usage
    • Unique shared security model
    • Mutations - add new functionality and improvements simple and fast
    • Forgetfulness - a blockchain cleaning mechanism
    • Low validator requirements and mobile validation
    • AI layer
    • Quantum future
    • Bring your social value to alternative economy
    • Ecosystem & Future services
  • Other resources & links
    • Official links
    • Brand assets
    • Partnerships
    • Tokenomics
    • 📚Glossary & Taxonomy
      • Our repositories and codebase
      • Architecture
      • Types of transactions
      • Types of accounts
      • Virtual machines
      • Consensus
      • RWX codeless smart contracts
  • Wallets usage
    • Wallets to work with WVM and native environment
    • EVM compatible wallets
  • build core and join network
    • ☁️Build the core
      • Build process
    • 🕸️Networks
      • Testnet
        • Your own private testnet
          • Netrunner
          • Netrunner and PM2
        • Public testnets
          • Testnet faucets
          • Setup testnet node
      • Mainnet
        • Setup mainnet node
    • 🪙Staking
      • Default staking
        • Staking
        • Unstaking
        • Native liquid staking
      • Multichain multiasset staking
        • Supported networks and tokens
        • Full list of supported assets
        • Work with native coins
        • Work with ERC-20 tokens
        • Work with ERC-721 tokens
        • Other
          • Work with Bitcoin, Litecoin and Doge
          • Work with XRP network
          • Work with TRON network
          • Work with Solana
        • Social value points
          • Telegram
          • Github
          • Instagram
          • Facebook (Meta)
          • YouTube
          • LinkedIn
          • Twitter
          • Discord
          • TikTok
          • Spotify
          • Hirsch index
          • Business value
        • Add your own asset
        • Connect your stakes from EigenLayer, Karak, Babylon, Solayer, etc.
      • Claiming rewards
    • 🕵️Become a validator
    • Mobile & low power devices validators
    • ⚙️Customizations
      • Create own mutation
      • Create own plugin
      • Run your node over TOR
      • Plugins usage
    • Explorers and how to use them
      • Public Explorer
      • Your own custom explorer
      • Usage guide
        • Network Parameters
        • Searchbar
        • Network Info
          • Epoches data
          • Hostchain checkpoints
  • Web1337
    • Web1337 intro
    • 🟢Simple API requests
      • Block API
      • Epoch API
      • State API
      • Misc API
      • Consensus related API
      • Transactions API
    • 🟠Transactions and smart-contracts
      • Useful advices & FAQ
      • 🔐Default Ed25519 transactions
      • 🤝BLS multisig transactions
      • 🛡️TBLS thresholdsig transactions
      • ⚛️Post-quantum transactions
      • 📃KLY-WVM - deploy and interact with the smart-contract to WASM vm
        • Interaction with a smart-contract
      • 📃KLY-EVM - deploy and interact with the smart-contract to EVM
        • Interaction with a smart-contract
      • Transfer coins between EVM and native environment
    • 🔴Advance Web1337 usage
      • Parallel execution
      • Interaction with a system smart contracts
      • 🪄Abstraction
        • 🦸‍♂️Account abstraction 2.0
        • 💾Storage Abstraction
          • 🔃Manual deployment of the storage for your contract
          • ☄️Dump EVM & WASM contract storage
          • Pay for storage rent
        • ⛓️Chain abstraction
      • 🌩️Thundercloud
        • 🏷️Using KLY Aliases in transactions
        • 🦾Deploy KIP
      • Using boosts & subscriptions
    • 🌐Networking
      • 🙈Using proxy
      • ⚡Interact with node via websockets
  • Smart Contracts and vms
    • Intro
    • 👩‍💻KLY-EVM
      • Smart contracts examples
      • 🧙‍♂️Magic address
      • Beyond the VM
        • ❎Call WASM from EVM
        • ❎Call JS from EVM
    • 👨‍💻KLY-WVM
      • Smart contracts examples
      • 🔁Simple cross-contract call (WVM-WVM)
      • Beyond the VM
        • ❎Call EVM from WASM
        • ❎Call JS from WASM
    • Containers
    • 🤓Writing smart contracts
      • Get random value from contract
    • 🧠Advanced VMs usage
      • 🔐Cryptography
        • 🎲VRF
        • ⚛️Post-quantum cryptography
        • 👀zkSNARK
        • 🤫Secure Secret Sharing
        • 🤹Using MPC
        • 🙈Using FHE
      • ⛈️Thundercloud
        • 👀KLY Oracles
          • ⏳Get the real time
          • 🌏Call any API
  • 🗺️RWX contracts
    • ℹ️Intro to real-world-execution smart contracts
    • How to use RWX contracts in your project or business
      • Web2 usage
        • User-User - agreements between default people
        • User-Business - agreements between customer and business
      • Web3 usage
        • Use in standalone blockchain projects
        • Use in DApps
    • 🤝Create RWX contract and deploy with Web1337
    • 🕵️‍♂️Become verifier
  • 👀Interesting features you must know
    • 😦Return of lost funds
  • Misc
    • 🏷️KLY Aliases
      • Web2 domain to KLY Alias
      • Web3 domain to KLY Alias
      • Social media handle to KLY Alias
  • Bots
    • 🤖Intro
  • Nodes management and maintaining
    • Core version update
    • State pruning
    • Launch own PoD (point of distribution)
    • Recovery process
    • Fast sync
  • Shared security usage
    • For blockchain networks
    • For DApps
    • For bridges
    • For oracles
Powered by GitBook
On this page
  • Intro
  • Generate BLS keypair(s)
  • BLS => Ed25519 transaction
  • BLS => BLS(multisig address) transaction
  • BLS => TBLS(thresholdsig address) transaction
  • BLS => PostQuantum(Dilithium/BLISS) transaction

Was this helpful?

Edit on GitHub
  1. Web1337
  2. Transactions and smart-contracts

BLS multisig transactions

PreviousDefault Ed25519 transactionsNextTBLS thresholdsig transactions

Last updated 3 months ago

Was this helpful?

Intro

Shortly, the typical keypair looks like this:

let publicKey = '0xabe301a20289d1e014c69906febbee42626e084dc93f70c689803e163963101fc90a3674576f86ff90ba9c71310685f1';
let privateKey = '69bfb956053e034b1b7d8b634c9bb8acd1b5743fab64245fad4b1472f63799a9';
  • 48-bytes, 0x-prefixed hex encoded public key(used as address)

  • 32-bytes hexadecimal private key

  • 96-bytes hex encoded signature

Generate BLS keypair(s)

BLS => Ed25519 transaction

import Web1337,{crypto} from 'web1337';


let web1337 = new Web1337({

    chainID:'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
    workflowVersion:0,
    nodeURL: 'http://localhost:7332'

});


let publicKey1 = '0xabe301a20289d1e014c69906febbee42626e084dc93f70c689803e163963101fc90a3674576f86ff90ba9c71310685f1';
let privateKey1 = '69bfb956053e034b1b7d8b634c9bb8acd1b5743fab64245fad4b1472f63799a9';

let publicKey2 = '0x8486ccde87fe2603815587a64bd43596d45b383d12563e6b513a9ca033ec9974490f9d577125bbd2b80ada893476a603';
let privateKey2 = '001b9abf2e6d23e13b30a4d35242a11848530f5e40a0fea8c3c50d2902c6c056';

let publicKey3 = '0x87960819a282b2092825c73ac3afbe2e1d5680dff8e00c1f10851ab0b025ae45ac46698d6c0dfda229e2a187bde9690c';
let privateKey3 = '5eca1e38f579064091c4c84eab47b5b5f2a0256847674e6f590879c2dc1605e0';

let publicKey4 = '0x965c986dc91c1a45b6a6d24bb7b8509e9c80f6e77827de1e70737bdeeb23ef3362864da538da57a57384c17dcc9a3fc7';
let privateKey4 = '1635f5c69f695673e83184aba52316a9d2a458016e791ae0180d8c42d05a144c';



// General pubkey retrieved from 4 friends public keys
const rootPubKey = crypto.bls.aggregatePublicKeys([publicKey1,publicKey2,publicKey3,publicKey4]);

// Root pubkey of 3 friends who want to use account - imagine that 1 of friend(the 4th one) is AFK
const aggregatePubKeyOfThreeFriends = crypto.bls.aggregatePublicKeys([publicKey1,publicKey2,publicKey3]);

// Array of pubkeys of friends who dissenting to sign
const arrayOfAfkSigners = [publicKey4];

const recipient = "nXSYHp74u88zKPiRi7t22nv4WCBHXUBpGrVw3V93f2s";


let payload = {

    active: aggregatePubKeyOfThreeFriends, // aggregated pubkey of ACTIVE signers who participate in THIS transaction

    afk: arrayOfAfkSigners, // here you should paste array of parties who is afk

    to: recipient,

    amount: 13.37

};



const fee = 0.03;

const nonce = await web1337.getAccount(rootPubKey).then(account=>account.nonce+1);

const txType = 'TX';


// Now 3 sides need to sign the same tx data locally(on their devices)

let signature1 = web1337.signDataForMultisigTransaction(txType,privateKey1,nonce,fee,payload);

let signature2 = web1337.signDataForMultisigTransaction(txType,privateKey2,nonce,fee,payload);

let signature3 = web1337.signDataForMultisigTransaction(txType,privateKey3,nonce,fee,payload);


console.log('\n============ Partial signatures ============\n');
console.log(`[0] ${signature1}`);
console.log(`[1] ${signature2}`);
console.log(`[2] ${signature3}`);


let aggregatedSignatureOfThree = crypto.bls.aggregateSignatures([signature1, signature2, signature3]);

console.log(`\n\nAggregated signature of 3/4 parties : ${aggregatedSignatureOfThree}`);


// Finally, build the transaction that will be sent to network
let finalTx = await web1337.createMultisigTransaction(rootPubKey,txType,aggregatedSignatureOfThree,nonce,fee,payload);

console.log("\n\nFinal tx to sent to mempool => ",finalTx);

Output:

============ Partial signatures ============

[0] a1bc9a2441fcb8662bf1f2503a1f2c23500d8a5b27d0d13e29a8f9edc0f74c2e63c09db70b03fd3b698c62c229beb7ea114dcb96296032fdedcb9f6ba8f8825f26ba3b367cd0e5dd1b46d085956c6113463b4022b7387a33d048a32ae39ed318
[1] ae687c9b452b9d8ba634294f20e1932d9f94635a938c953c50478b3ba50ce5afab4e3d4335ada2e0e425d0b0b1ee4750144b27109bb4186da04899c34749926fcbca09dd83dd80511baaf34c2ea1334c2ff7477bddf43ffa31eafdcb0ef76b0a
[2] b69f20b43e7e303165d2f698464d768665602f4aaa4fb880de69cfa2d5610c9103548482608f8e4778dbd4ce0e331d37140c9ef05435f7c48e37061bb6df49795801ddccc8a0607fb8f08bd66116a484276c4a3af1bbe94a1d6959eb9f915a44


Aggregated signature of 3/4 parties : 8a1a30435c71aa0e58d755e61873f69f9c0afe9c092f12b3c4df98b3c664afa5d0db70bb1b7852b793be5c59eab56e080e5c05996ac31cd58df9149d95cf7d5ab004a85325cfc77e933ed34c4705aaf6f252ded33c9249f8821a4165158241e8


Final tx to sent to mempool => 

{
  v: 0,
  creator: '0xb89c4bf0b9dab0224201d06d46ed6cb49b94f34f8dc8feb0d7bad77caab5b41fc16531dce9ba2cba5784359d2b701cc4',
  type: 'TX',
  nonce: 1,
  fee: '3000000000000000000',
  payload: {
    active: '0x8b342d0ea511983d78865b53e75f203d6795d2ae5fbb77bf95858b5958d3dfc65f73139ce69746b7c2254841411a7949',
    afk: [
      '0x965c986dc91c1a45b6a6d24bb7b8509e9c80f6e77827de1e70737bdeeb23ef3362864da538da57a57384c17dcc9a3fc7'
    ],
    to: 'nXSYHp74u88zKPiRi7t22nv4WCBHXUBpGrVw3V93f2s',
    amount: '13370000000000000000'
  },
  sigType: 'M',
  sig: '8a1a30435c71aa0e58d755e61873f69f9c0afe9c092f12b3c4df98b3c664afa5d0db70bb1b7852b793be5c59eab56e080e5c05996ac31cd58df9149d95cf7d5ab004a85325cfc77e933ed34c4705aaf6f252ded33c9249f8821a4165158241e8'
}

Now, you can send this transaction:

let sendStatus = await web1337.sendTransaction(finalTx);

Then, go to explorer and check the status. Remind that TxID is Blake3 hash of tx signature, so you can get the TxID using this snippet:

let txID = web1337.blake3(finalTx.sig);

console.log(txID);

BLS => BLS(multisig address) transaction

Remember that in case you fund NEW recipient address, you need to add rev_t to payload. Otherwise - just paste recipient to payload.

import Web1337,{crypto} from 'web1337';


let web1337 = new Web1337({

    chainID:'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
    workflowVersion:0,
    nodeURL: 'http://localhost:7332'

});


let publicKey1 = '0xabe301a20289d1e014c69906febbee42626e084dc93f70c689803e163963101fc90a3674576f86ff90ba9c71310685f1';
let privateKey1 = '69bfb956053e034b1b7d8b634c9bb8acd1b5743fab64245fad4b1472f63799a9';

let publicKey2 = '0x8486ccde87fe2603815587a64bd43596d45b383d12563e6b513a9ca033ec9974490f9d577125bbd2b80ada893476a603';
let privateKey2 = '001b9abf2e6d23e13b30a4d35242a11848530f5e40a0fea8c3c50d2902c6c056';

let publicKey3 = '0x87960819a282b2092825c73ac3afbe2e1d5680dff8e00c1f10851ab0b025ae45ac46698d6c0dfda229e2a187bde9690c';
let privateKey3 = '5eca1e38f579064091c4c84eab47b5b5f2a0256847674e6f590879c2dc1605e0';

let publicKey4 = '0x965c986dc91c1a45b6a6d24bb7b8509e9c80f6e77827de1e70737bdeeb23ef3362864da538da57a57384c17dcc9a3fc7';
let privateKey4 = '1635f5c69f695673e83184aba52316a9d2a458016e791ae0180d8c42d05a144c';



// General pubkey retrieved from 4 friends public keys
const rootPubKey = crypto.bls.aggregatePublicKeys([publicKey1,publicKey2,publicKey3,publicKey4]);

// Root pubkey of 3 friends who want to use account - imagine that 1 of friend(the 4th one) is AFK
const aggregatePubKeyOfThreeFriends = crypto.bls.aggregatePublicKeys([publicKey1,publicKey2,publicKey3]);

// Array of pubkeys of friends who dissenting to sign
const arrayOfAfkSigners = [publicKey4];

const recipient = "0x8f079049121d5e2ae885bdc6581df9fb68eab94a7aa3ae54bfe1d1ac35aceefbb202f656b0c1b56d64583630612a9970"

const rev_t_for_recipient = 1; // imagine that this acccount is 2/3 multisig so allow 1 afk signer

let payload = {

    active: aggregatePubKeyOfThreeFriends, // aggregated pubkey of ACTIVE signers who participate in THIS transaction

    afk: arrayOfAfkSigners, // here you should paste array of parties who is afk

    to: recipient,
    
    rev_t: rev_t_for_recipient,

    amount: 13.37

}



const fee = 0.03

const nonce = await web1337.getAccount(rootPubKey).then(account=>account.nonce+1);

const txType = 'TX'


// Now 3 sides need to sign the same tx data locally(on their devices)

let signature1 = web1337.signDataForMultisigTransaction(txType,privateKey1,nonce,fee,payload);

let signature2 = web1337.signDataForMultisigTransaction(txType,privateKey2,nonce,fee,payload);

let signature3 = web1337.signDataForMultisigTransaction(txType,privateKey3,nonce,fee,payload);


console.log('\n============ Partial signatures ============\n');
console.log(`[0] ${signature1}`);
console.log(`[1] ${signature2}`);
console.log(`[2] ${signature3}`);


let aggregatedSignatureOfThree = crypto.bls.aggregateSignatures([signature1, signature2, signature3]);

console.log(`\n\nAggregated signature of 3/4 parties : ${aggregatedSignatureOfThree}`);


// Finally, build the transaction that will be sent to network
let finalTx = await web1337.createMultisigTransaction(rootPubKey,txType,aggregatedSignatureOfThree,nonce,fee,payload);

console.log("\n\nFinal tx to sent to mempool => ",finalTx);

Output:

============ Partial signatures ============

[0] a4a516b9b1094891db6820d6f03e194e389d679f0b3b634edc142c6ba444bc31bf10d8a959a7c8fcc55e1078541803ff14f3594549959c8fa81a9d448cfac856def1d37957f5adddefaeab1f53ddefbaa9525db460a91bd2f50f89a52ebd5633
[1] 9360299b103991a2ecbaf25233328b4a47da087f8d8d7457d9b24c85c27e530cd5ddb787ec736e7eea47165d38c2fe200bada413ad7a5d4d02bae8f9f23038b10f846fae4128004d6cf51b47974a62e7943923c8418812552a42af547aab7b61
[2] 869c5c7a92a8b8ea38ef6e636c13a286a6e3ee7a31a85cc573ed02d38afcc5381203958fbfd725c4fa9d245ae25fa7310486b2bf0f09f2917d0f1f5670e4bb7f4dd5512d6e95b58da3dc2a6719915d50ec8b685b1aaa8c0c2eecceaff710025e


Aggregated signature of 3/4 parties : b481810611e42a8b6f41abf3326d7c44ade5f2c87b0ccbce49206503e3f6ad32ad7d54bc9dec9323430bd638e26a18c007c7ba6bf9cf987b278533ea2cd94355e8b1db4b02048c78e41abced4b843687090ff3e683ade1e54176c4aa8fe283e5


Final tx to sent to mempool =>  {
  v: 0,
  creator: '0xb89c4bf0b9dab0224201d06d46ed6cb49b94f34f8dc8feb0d7bad77caab5b41fc16531dce9ba2cba5784359d2b701cc4',
  type: 'TX',
  nonce: 1,
  fee: '3000000000000000000',
  payload: {
    active: '0x8b342d0ea511983d78865b53e75f203d6795d2ae5fbb77bf95858b5958d3dfc65f73139ce69746b7c2254841411a7949',
    afk: [
      '0x965c986dc91c1a45b6a6d24bb7b8509e9c80f6e77827de1e70737bdeeb23ef3362864da538da57a57384c17dcc9a3fc7'
    ],
    to: '0x8f079049121d5e2ae885bdc6581df9fb68eab94a7aa3ae54bfe1d1ac35aceefbb202f656b0c1b56d64583630612a9970',
    rev_t: 1,
    amount: '13370000000000000000'
  },
  sigType: 'M',
  sig: 'b481810611e42a8b6f41abf3326d7c44ade5f2c87b0ccbce49206503e3f6ad32ad7d54bc9dec9323430bd638e26a18c007c7ba6bf9cf987b278533ea2cd94355e8b1db4b02048c78e41abced4b843687090ff3e683ade1e54176c4aa8fe283e5'
}

BLS => TBLS(thresholdsig address) transaction

The same as BLS => Ed25519 transaction but change the recipient to 48-bytes TBLS root key

BLS => PostQuantum(Dilithium/BLISS) transaction

The same as BLS => Ed25519 transaction but change the recipient to 32-bytes post-quantum address. See:

REMEMBER

In case you fund a NEW post-quantum account you need to add the post-quantum pubkey of recipient to payload

By default, you recipient have locally keypair like this:

let blissKeyPair = {

    pub: '001b4609d500e31a0a188911900aac07fb06f91566038104e90c01031707d6154701701a15046d07f5089f0c730c8515e712c90b5a130d10081bca0ab40c8f0027101501870ccb17041d691bac0c30162d11ff0566198710f308cd08b30be804261a040c530cb8042e16841623069200b9175410a5016a171e1ceb10f813261bae0acc06be176214471d7013530d92180a0dbd15c800fd09f700ed0a8616141a14095b08a71c3317031d78106602ef1c1f1a53097016df192905b50ad40b5c1d1c027e026b0ecb115417ae1b6f1c1101c60d3f1c12016010a309f8183411840d7d12d414071a5b10d1162111f712951b36066209500e1d137d1dbf055417e6075c0ce307460ff9040715b51d0000cc11cf1bd1194c0a2d19e901191c5306040c8002be0d19024f10b31b19152912fe06900de21b2e10110ab111f80b6403ac1b8505221bac09830e3501a1175705c7138e1db6035c09871c4c121706b70b560ac70c001d2305b0107117ef02c1178a13f010bb193004ca02bc035e036f109419770a2017f11dd00cb3016405b41604091206c61603085208fa0df0130912cb14cd187914b009e306440a3018ca0c5810c305400507103b1113016c0ead00100e3f02b6003410981cdf04c50d0213d61984110c0ba700ae0c8912f618a01a231bc81066010a1d051242103013ac05c30dae14030f890e1117b319a002a707f30923',
    prv: 'd112525a9435c29d732592e9ec90eba2ae7b1ae2c0d3ac9b6d6ce662ca5140abb02bc846c7f54f955a84fed543107c9180366d025324aac2d253ec60515cf9ee',
    address: '1826d3782d53b127c53129fe67f4a3e3c1140feb2af36a0517077297a6e867e5'

};

Case 1: His account already in state and has balance

In case recipient account already exists, just ask him for address.

In this case your payload of transaction will look like this:

let payload = {

    to: "1826d3782d53b127c53129fe67f4a3e3c1140feb2af36a0517077297a6e867e5",
    
    amount: 13.37
    
}

Case 2: Recipient account will be new and didn't exists before tx

So, if you fund new account the payload of your transaction should be:

let payload = {

    to: "1826d3782d53b127c53129fe67f4a3e3c1140feb2af36a0517077297a6e867e5",
    
    amount: 13.37,
    
    pqcPub:"001b4609d500e31a0a188911900aac07fb06f91566038104e90c01031707d6154701701a15046d07f5089f0c730c8515e712c90b5a130d10081bca0ab40c8f0027101501870ccb17041d691bac0c30162d11ff0566198710f308cd08b30be804261a040c530cb8042e16841623069200b9175410a5016a171e1ceb10f813261bae0acc06be176214471d7013530d92180a0dbd15c800fd09f700ed0a8616141a14095b08a71c3317031d78106602ef1c1f1a53097016df192905b50ad40b5c1d1c027e026b0ecb115417ae1b6f1c1101c60d3f1c12016010a309f8183411840d7d12d414071a5b10d1162111f712951b36066209500e1d137d1dbf055417e6075c0ce307460ff9040715b51d0000cc11cf1bd1194c0a2d19e901191c5306040c8002be0d19024f10b31b19152912fe06900de21b2e10110ab111f80b6403ac1b8505221bac09830e3501a1175705c7138e1db6035c09871c4c121706b70b560ac70c001d2305b0107117ef02c1178a13f010bb193004ca02bc035e036f109419770a2017f11dd00cb3016405b41604091206c61603085208fa0df0130912cb14cd187914b009e306440a3018ca0c5810c305400507103b1113016c0ead00100e3f02b6003410981cdf04c50d0213d61984110c0ba700ae0c8912f618a01a231bc81066010a1d051242103013ac05c30dae14030f890e1117b319a002a707f30923"
    
}

Read detailed information

🟠
🤝
⚛️Post-quantum transactions
here