bloxbean / yaci-devkit

A set of dev tools for development on Cardano.
https://devkit.yaci.xyz
MIT License
44 stars 9 forks source link

Well defined default addresses #29

Open SebastienGllmt opened 5 months ago

SebastienGllmt commented 5 months ago

If you use popular tools to spin up local EVM networks like hardhat/anvil, it will print out a bunch of known key pairs that are part of the node by default.

The reason this is really helpful is that is allows people to write tools that default to using these addresses when running on localhost knowing that it will work without any user configuration changes if the user is using hardhat/anvil

It would be useful if yaci also did this. Concretely, in Paima we want users to be able to spin up local nodes with yaci and have the Paima configuration (which requires private keys for account abstraction and other similar things) to just default to these accounts knowing they will exist

Example of hardhat ↓ image

SebastienGllmt commented 5 months ago

Notably, the keys all these tools generate all seem to come from the recovery phrase test test test test test test test test test test test junk

However, we can't easily use 12-word phrases in Cardano because some tools are hard-coded to assume those are old Byron addresses. Therefore, I propose we use this 24-word recovery phrase instead

test test test test test test test test test test test test test test test test test test test test test test test sauce

For this mnemonic, I got the following address & keys

Account #0: addr_test1qryvgass5dsrf2kxl3vgfz76uhp83kv5lagzcp29tcana68ca5aqa6swlq6llfamln09tal7n5kvt4275ckwedpt4v7q48uhex
Payment key: ed25519e_sk1sqr5ymxr5377q2tww7qzj8wdf9uwsx530p6txpfktvdsjvh2t3dk3q27c7gkel6anmfy4a2g6txy0f4mquwmj3pppvy3046006ulussa20jpu
Staking key: ed25519e_sk12rgp4ssmuwe6tgsqwhf255dyj99vwfezsltnx2zg9ptwxvl2t3dumf06jg0rgyw0evktn24y9kshw8jtch3d6h2ppswtswywaa633vq34g6r4

Account #1: addr_test1qpqy3lufef8c3en9nrnzp2svwy5vy9zangvp46dy4qw23clgfxhn3pqv243d6wptud7fuaj5tjqer7wc7m036gx0emsqaqa8te
Payment key: ed25519e_sk1sz7phkd0edt8rwydm5eyr2j5yytg6yuuakz9azvwxjhju0l2t3djjk0lsq376exusamclxnu2lkp3qmajuyyrtp4n5k7xeaeyjl52jq8r4xyr
Staking key: ed25519e_sk10p46hyz6h34lr5d6l0x89hrlhenj7lf9cha7ln8a6697jwh2t3dhgkz0lcr896rv773mupcc239vcs06uet0a44yqsrzdlx69wwy8tswkp56t

Account #2: addr_test1qr9xuxclxgx4gw3y4h4tcz4yvfmrt3e5nd3elphhf00a67xnrv5vjcv6tzehj2nnjj4cth4ndzyuf4asvvkgzeac2hfqk0za93
Payment key: ed25519e_sk1gqv3vkxkcg0pwqm6v9uw7g79z7mm8cn4j5xxwms60cuuuw82t3dcjn8pzsc26wn5sl93mzk3hex8uy4syf9e6xhqxp67cyz3mnka4uc0r9as0
Staking key: ed25519e_sk12qd8w9g5342kp8wpv8h3d53c40j8sgmge82m49kdlrhw5s82t3d5y4xwr4rdxyxj66heh7c7788npmvnlexqd7a6dxvz6amq4hxz2sgteyf6g

Account #3: addr_test1qqra0q073cecs03hr724psh3ppejrlpjuphgpdj7xjwvkqnhqttgsr5xuaaq2g805dldu3gq9gw7gwmgdyhpwkm59ensgyph06
Payment key: ed25519e_sk1spvy8qz8fdnqadfpvvkyyxt7gacxql644vf2dluj8lees0h2t3dean3h530f97ek3l4prclpy6qxcutzupym6rv9nxmwr733ea8j4gcl3haeh
Staking key: ed25519e_sk15zd6l7z66zhmuxlw9mgt4wg9wqrx0lt058whnvsz9yqe2w02t3dh423fmrmtt4ru0d2yvudk993x8v0x6j308ev89w9prgp3cu7q60s40s8h4

Account #4: addr_test1qp38kfvcm4c39yt8sfgkp3tyqe736fz708xzxuy5s9w9ev43yh3sash5eeq9ngrfuzxrekpvmly52xlmyfy8lz39emhs2spswl
Payment key: ed25519e_sk1yzsz6qsaxxvj4m4qny937gs2v56v0sfqam90nmgfefhrv002t3d5h0vr5xvr56hrlhy0ganpg4qkwq2khxq6809r62uqtdlc7eya9wgwtf9aq
Staking key: ed25519e_sk1rzz79a3g5dftz5dvl83j6v5n6mnpxmneemwcaek38cu9gw82t3dejlazt53amypxkly076u3xl60042wtu8h2t9uq6qrz4e3gvwx29qwc0y4g

Account #5: addr_test1qrrv7774puml0exvzc0uqrc8axezy6a925kv4ucdx906qy6mhjxtmx44x70ndr7g6dgqcdaf69q8fnrdmtvfud5x7rsqvsuqx5
Payment key: ed25519e_sk1mqgzsggq4y8z3s9ap0zta7y4xfcfm2pxf5ya3hwacvmlwd82t3deduqhheynwp04a2cvhtvre658w0cnx2cac49ujm5k4jl6mnhkq6gyl35nx
Staking key: ed25519e_sk1hrfx6l6xjxvyzth02704fz6csk7np94mvdfpl8dmgfvkkth2t3de6c55j4d8z5a9f8fly3d3c4ccvh4zawh07s7udxa03j63vv6nwaq0uk0m3

Account #6: addr_test1qpgkf2ccvu2uscmcqgy4dkyjeae0va3kk7yk04nuleekq3u3xrwgnnm6n0yfzz0e8x2kkehex2f6mexrjg9h9l2qhm4qkms53s
Payment key: ed25519e_sk19qu94cfggqdafymq8znpv5xkrj0ggssmlvsytpcev2ldy002t3d3qzxt9468nxszkhmpvehg54hql4sm2lenym5rsqf6hrl37kg0ksg3qmlew
Staking key: ed25519e_sk14pfa52uet4ce6krepxncnazkq2zngygr4dth7tzuzkahz002t3dhttequn5f8s0s6knjm343kc94htnmlvwpza4vpjg0jdr9sa36a5q6a5ymg

Account #7: addr_test1qq7a8p6zaxzgcmcjcy7ak8u5vn7qec9mjggzw6qg096nzlj6n7rflnv3x43vnv8q7q0h0ef4n6ncp5mljd2ljupwl79s5mqneq
Payment key: ed25519e_sk1rz764r3hr8sckhrcydztu7rsav6uqc7d7xutnxr4vh826wl2t3de27ukls5d0qjzj3plu5q75xuhyje8whw7cq7drj6sl9ms6pgs5vc384ywj
Staking key: ed25519e_sk1qztf2xzznhy76gunnt0lzptnjhzheth64gau0h496jzfgdh2t3dac0wr5yp5n42kz4jv4264a82kg73t3fqpp34eq284rvvdjgz0x2gquaghd

Account #8: addr_test1qzyw0ensk3w2kgezk5vw77m0vmfs4mqdjg7ugclyvuy357g0vaukh8a8zgj09prvaw70f9gvz8sypmsjf5c0dctyhn2slcvsjn
Payment key: ed25519e_sk1mrq79v0seg8lnu9et3txtgr8f6me33knx5m7qfmje6yxjd82t3dkyt6jwnwfg35npnwurulp5rvk9dzw9hlrh4xsrc4a5gnege0k0qg3ftl8s
Staking key: ed25519e_sk1gq2tajwd8t9whhuyxr8kzfklpesfvsyllcdt8n08nrxqgdl2t3d3apuulmctwv7pup8d52c7jmhzsf8xj00v832wcp4fqzewevvzz6gr4w02k

Account #9: addr_test1qrrshpppv9uq95lj89tv4vv40cwnqmx5szzcndqhvr5hjfltl4s98wsjkwpg3v4k6h2vgcvdd2xwt82stq8fcmmsft6s8dzp8f
Payment key: ed25519e_sk1xqleykm4zyggadyt6hunm6laqgd6yatcumyptvu8v8uf5wh2t3djrry8d3dlz2cve6hsc8a7vvuqqdud0h7vvyuhhmc0j0mw6pkaawcgh2ycr
Staking key: ed25519e_sk1uqzvs53kr2jv6cfzwj0usczr3v8dqg32ydjf5h0fqlxd7d02t3dm5rhrz57j80gz5v3zzvlch9f6su9rnkhqm6d6tlgmy9lx6y72mtcu79lzk

Account #10: addr_test1qrqfxwuz8rm0xvewfrp5eudgup24jsan8n22h3f6a7mavyjt0njqm4ykhhqzkdrq9ua8w0lhen8wsuuerexgsehn5u9syjlrxr
Payment key: ed25519e_sk1nped0y8f849sgz5tgw307uj2a3l084r3qvjmqsynn9dxz0h2t3da6e0z5h0c26nc9c6k46kdcjxjq89c5nugfd7sj2vn989le92csdqzdhldz
Staking key: ed25519e_sk1xqmy9ycnz02pngjhck4f6ussy4jnzd96f5zl0hl2qn9ykwl2t3dsrhvteyqpxw4cd0w8rs7z6rhj2dpwtmwjha6wgkr6knhtvkzyvkswm987q

Account #11: addr_test1qp5l04egnh30q8x3uqn943d7jsa5za66htsvu6e74s8dacxwnjkm0n0v900d8mu20wlrx55xn07p8pm4fj0wdvtc9kwq7pztl7
Payment key: ed25519e_sk19zen3lj20xr60c298p0jvpzgnd78vzj7hp796c4mtt3w2dl2t3dkyvhzdt4ugcjwqs8ndc869gzqrygsgaf33p5taxh75ka53ef6drgf6kvw5
Staking key: ed25519e_sk1srj45s76tllvekvazx2cdm236tm487prg740r8y4s663ywl2t3d43jxpyv6y8ul9xuzpunryumcqkzutkfsuhes2ypefn5k8njnm2vstmhefx

Account #12: addr_test1qpcf5ursqpwx2tp8maeah00rxxdfpvf8h65k4hk3chac0fvu28duly863yqhgjtl8an2pkksd6mlzv0qv4nejh5u2zjsshr90k
Payment key: ed25519e_sk1dpv5hvnymhtyx79h55z0wz2pttk0tf6dwz67xu83uhukcd82t3d5tx2sr9uvl3a9cfjsw9t7jlt8m2ln0qaezdq6ax7myhj8828m5egd00rt8
Staking key: ed25519e_sk16z67pkc7mal30ewl09z5qt4chltu3sa5tks2tkwtffdkzw02t3dk8qxkll9h9064c544g27693sqgsvvl0exesuvalrc8p9lav8lyzs869c0y

Account #13: addr_test1qr79wm0n5fucskn6f58u2qph9k4pm9hjd3nkx4pwe54ds4gh2vpy4h4r0sf5ah4mdrwqe7hdtfcqn6pstlslakxsengsgyx75q
Payment key: ed25519e_sk1vpkzkcn40jqvjjvqgexe5vrkr2ywhucfx7lj7yuvr2puk002t3ds0w3u9dhrvth5eql56u2c6zww5eg2568vj986lzhs0r5sttv4v7g04c2ru
Staking key: ed25519e_sk1crlzxz9ve605cle3pt4jadsp68yln29adxg6ntxy3pepqs82t3djl96cmfd5kw2s3e3evre72cjqfhqh76lkeuqt94xa0fmf6e3exfs5fpw9w

Account #14: addr_test1qqe5df3su6tjhuuve6rjr8d36ccxre7dxfx2mzxp3egy72vsetrga9el2yjke2fcdql6f6sjzu7h6prajs8mhzpm6r5qpkfq9m
Payment key: ed25519e_sk15qpedlqhwxhkctvpvn4s9fxfmscwy3mh9mkssrnwx5wfqw02t3d5wh6stwklnxr9jqfqlakl2s2z6p2lnz5xknvu62zt62zjjafs6yshefmh3
Staking key: ed25519e_sk16rff3sgxldm9ksxsefe75p04wvaazz9ymr5m6s4e5crvz0h2t3dnyzn66zqtgv32q47qkuhvf5jhcf3jx05whnq3657mjey3ffw7hpch9pd4h

Account #15: addr_test1qq5tscksq8n2vjszkdtqe0zn9645246ex3mu88x9y0stnlzjwyqgnrq3uuc3jst3hyy244rrwuxke0m7ezr3cn93u5vq0rfv8t
Payment key: ed25519e_sk14z9et30gwx7d0c24yrpklheh905936ez66p5rf27pux7sw02t3dsa7yqzf7xcqyvrlp5v4k0x4rldgrxuzjaucu0c6gjt0dynx8sukgcffxnv
Staking key: ed25519e_sk1fref9jndwaw6tn2xlc4nlwkl824auga85svj5v5m60g3yw82t3d7syehntq9h9wna4pwr5g53khjehpaklqh7zcxauuyu2tw0vwmkqca9v3q0

Account #16: addr_test1qp0qu4cypvrwn4c7pu50zf3x9qu2drdsk545l5dnsa7a5gsr6htafuvutm36rm23hdnsw7w7r82q4tljuh55drxqt30q6vm8vs
Payment key: ed25519e_sk13qpmqegclg7ft2ce5l89jq2wjg48rg7n3gup9shyy3p22w82t3dujk49l4843nmk2para5s372l8vmzfkxmku3egr5vgtalfjm3hzwqnjamxh
Staking key: ed25519e_sk14rkdqavts4pgg8mcweewrknu37eflyc32q93spy5k5m4zd02t3dcp4vsyv7jlx63e7hpr0zyz3z9tvrzqu2d9jwk4akedvyyy9taqrswkejyv

Account #17: addr_test1qqm87edtdxc7vu2u34dpf9jzzny4qhk3wqezv6ejpx3vgrwt46dz4zq7vqll88fkaxrm4nac0m5cq50jytzlu0hax5xqwlraql
Payment key: ed25519e_sk15qzuqn38va38m5sx3lj0wyqsstgtuwalmldqf20xu3e97sh2t3d6yhpz4tk44r026c60tluvfv4qkh8ccjw228zd5l6a9qccefrx34qldjfh9
Staking key: ed25519e_sk1ep4szn8m6xyajgr4vf2uayulh4yq3f4nqqueep7y9pfvjd82t3d6573yf23hcgkx2aq3u9uuehl97d7leq8n3d2zd7gsfdf87c7fpzsj9m0sk

Account #18: addr_test1qrzufj3g0ua489yt235wtc3mrjrlucww2tqdnt7kt5rs09grsag6vxw5v053atks5a6whke03cf2qx3h3g2nhsmzwv3sgml3ed
Payment key: ed25519e_sk1ppu7cwx5vd8he3eck6e796t3ucnpqe4z8672x6h32khrjsh2t3dnq2f6qvyp3p3gtmgchw0jdseu57296pdlre3mql98vcgdy50hxsgfn77s3
Staking key: ed25519e_sk14q9d4kyagaa5glcj938xhsdhhrze2747dmjfupww4833yw82t3d5ek5emhyn7vn4qumdqzkqleqma3q4lks4mfhfqfnww8szm9u2wfs7v99es

Account #19: addr_test1qrh3nrahcd0pj6ps3g9htnlw2jjxuylgdhfn2s5rxqyrr43yzewr2766qsfeq6stl65t546cwvclpqm2rpkkxtksgxuq90xn5f
Payment key: ed25519e_sk1ercgylcdszp5zt8ehufuyfujwtgc28737avv0dy0fqzexd02t3dsazn9xegp7qacxplnjlwhgnnwjv9z4y2yr0yp8qc4xp9n7zdq6hql493xp
Staking key: ed25519e_sk13p8jen4fuqfvagsvpjs770am2ytrn072pvh7wyvdvrw6kvh2t3dad98mxt2savj4sgfe6gzmcwewt7649waymclrnts0ddy03ke3vkc9m9gut

I double-checked these are the same as generated by both Yoroi & Eternl

I generated these using the following script with CML

import wasm from '@dcspark/cardano-multiplatform-lib-nodejs';
import bip39 from 'bip39';

const baseWords = 'test '.repeat(23) + 'sauce';

const rootKey = wasm.Bip32PrivateKey.from_bip39_entropy(
  Buffer.from(
    bip39.mnemonicToEntropy(baseWords),
    'hex'
  ),
  Buffer.from('')
);

for (let i = 0; i < 20; i++) {
  const accountKey = rootKey.derive(1852 + 0x80000000).derive(1815 + 0x80000000).derive(i + 0x80000000);
  const paymentKey = accountKey.derive(0).derive(0);
  const stakingKey = accountKey.derive(2).derive(0);

  const baseAddress = wasm.BaseAddress.new(
    wasm.NetworkInfo.preprod().network_id(),
    wasm.Credential.new_pub_key(paymentKey.to_public().to_raw_key().hash()),
    wasm.Credential.new_pub_key(stakingKey.to_public().to_raw_key().hash())
  );

  console.log(`Account #${i}: ${baseAddress.to_address().to_bech32()}`);
  console.log(`Payment key: ${paymentKey.to_raw_key().to_bech32()}`);
  console.log(`Staking key: ${stakingKey.to_raw_key().to_bech32()}`);
  console.log();
}
t baseAddress = wasm.BaseAddress.new(
    wasm.NetworkInfo.mainnet().network_id(),
    wasm.Credential.new_pub_key(paymentKey.to_public().to_raw_key().hash()),
    wasm.Credential.new_pub_key(stakingKey.to_public().to_raw_key().hash())
  );

  console.log(`Account #${i}: ${baseAddress.to_address().to_bech32()}`);
  console.log(`Payment key: ${paymentKey.to_raw_key().to_bech32()}`);
  console.log(`Staking key: ${stakingKey.to_raw_key().to_bech32()}`);
  console.log();
}
satran004 commented 5 months ago

Thanks @SebastienGllmt for trying out DevKit.

It's really a good idea to support a set of default addresses out of the box.

I verified the above mnemonic with Java code and was able to generate the same keys.

One simple approach for now could be for DevKit to automatically top up these addresses with a single transaction during the first time node startup. So, with a 1-second block time, there would probably be at most a 2-second delay in startup.

Later, we can explore adding these addresses directly to the genesis file of the node.

What should be the default amount for these addresses? 10,000 ADA?

Note: Just adding my code here in case anyone is interested in deriving the same in Java.

String mnemonic = "test test test test test test test test test test test test test test test test test test test test test test test sauce";

for (int i = 0; i < 20; i++) {
            DerivationPath derivationPath = DerivationPath.createExternalAddressDerivationPathForAccount(i);
            var account = new Account(Networks.testnet(), mnemonic, derivationPath);

            System.out.println("Address # " + i + " " + account.baseAddress());
            System.out.println("Stake Address: " + " " + account.stakeAddress());

            var prvKeyBytes = account.privateKeyBytes();
            String paymentKey = Bech32.encode(prvKeyBytes, "ed25519e_sk");
            System.out.println("Payment Key: " + paymentKey);

            var stakingKey = Bech32.encode(account.stakeHdKeyPair().getPrivateKey().getKeyData(), "ed25519e_sk");
            System.out.println("Staking Key: " + stakingKey);
            System.out.println("\n");
}
matiwinnetou commented 5 months ago

+1, great idea.

SebastienGllmt commented 5 months ago

What should be the default amount for these addresses? 10,000 ADA?

Yeah I think 10K is fine. I guess the most expensive thing somebody might want to do during startup is spin up multiple pools, but they're only 500 ADA each so 10K should be enough. It could be higher though (ex: 100k)

SebastienGllmt commented 5 months ago

with a single transaction during the first time node startup

I guess the tricky part about Cardano is that it can't be that just the addresses and balances are well-defined, but you also need to know the tx id that created these initial addresses so that you can reference them in an input

However, I don't think we can easily enforce a tx id that will forever be constant (since any change to the genesis block(s) modifies this), so we'll just have to tell people that there are known UTXOs somewhere and they will have to query to know the tx id to spend them as inputs. (still an improvement over now where there are no known addresses at all)

satran004 commented 5 months ago

@SebastienGllmt

I have added default addresses to the Shelley genesis file (under the 'initialFunds' property), and it's working perfectly. All default addresses are automatically funded. Also, the initial utxos for these addresses are always the same. The initial transaction hash for a default address is equal to blake2b256(addressBytes), so it's deterministic in this case.

Probably, we can display the address, secret keys, and UTxOs with balances for all default addresses during the first start. May be it's too much info.

Next, I need to add these address to the show-default-account command output.