Aaron J. Milius
3 years ago
committed by
Brooke L. Rediker
90 changed files with 1779 additions and 179 deletions
-
1.gitattributes
-
15CAStore/genesis.yml
-
16CAStore/nullblock.yml
-
15README.md
-
18admin/config.md
-
21admin/index.md
-
18admin/keygen.js
-
22admin/keygen.md
-
19admin/manual-registration.md
-
27admin/new-settings.md
-
47admin/register.js
-
21admin/register.md
-
19admin/settings.md
-
15api/audit.md
-
15api/cmd.md
-
22api/config.md
-
16api/env.md
-
16api/explore.md
-
22api/getblock.js
-
24api/getblock.md
-
51api/index.md
-
45api/nodes.js
-
31api/nodes.md
-
20api/peerid.js
-
15api/peerid.md
-
53api/transaction.js
-
43api/transaction.md
-
4bin/apirun
-
16bin/signtx.pl
-
5bin/yml2json.sh
-
34config.yml
-
23config0.yml
-
21curltest.sh
-
10docs/UTXO.md
-
111docs/block.js
-
39docs/block.md
-
30docs/chain.js
-
22docs/chain.md
-
23docs/difficulties.md
-
27docs/explorer.md
-
57docs/genesis.js
-
27docs/genesis.md
-
74docs/heads.js
-
23docs/heads.md
-
5docs/index.md
-
44docs/info.js
-
29docs/info.md
-
30docs/minepool.js
-
30docs/minepool.md
-
24docs/mining.md
-
30docs/nodes.js
-
21docs/nodes.md
-
22docs/notes.md
-
4docs/pow.js
-
27docs/status.md
-
30docs/test.js
-
42docs/test.md
-
51docs/transactions.js
-
46docs/transactions.md
-
28docs/txpool.js
-
21docs/txpool.md
-
32eckeygen.pl
-
2lib
-
10nodes/cloneit.sh
-
2salts/Genesis.yml
-
BINsecrets/keys.yml
-
BINsecrets/nicknames.yml
-
11t/blockaddr.t
-
6t/createtx.t
-
BINt/eckeys.t
-
2t/genesis.t
-
3t/hashcash.t
-
7templ/config.yml
-
1templ/genesis.yml
-
14templ/runtest.sh
-
17templ/runtime.yml
-
1templ/salt.yml
-
20templ/tx.yml
-
1templ/tx02.json
-
23templ/tx02.yml
-
35templ/tx03.json
-
17templ/txcb01.yml
-
17templ/txcoin.yml.sig
-
6templ/txexample.yml
-
3templ/txgen.yml
-
2templ/txnull.yml
-
19templ/txudj.yml
-
1templ/txvalid.json
-
18templ/txvalid.yml
-
11txpool/txgen.yml
@ -1,15 +0,0 @@ |
|||||
--- # genesis block |
|
||||
ver: 0 |
|
||||
data: |
|
||||
seq: 0 |
|
||||
payload: /ipfs/QmWM48KvyK9YyPjJt69erxVPN3nbXVMgZWrncRJhAVkGAv |
|
||||
comment: "This is the genesis block" |
|
||||
meta: |
|
||||
seed: 0xb3560762 |
|
||||
salt: ~ # used in address computation |
|
||||
txroot: ~ |
|
||||
audit: |
|
||||
peerid: Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq |
|
||||
tics: 1623830817245864895 |
|
||||
ip: 83.78.4.228 |
|
||||
prev: ZdtrjkYsAYUeBCs4DRjtVYwPevpxvHjGT2PRauANr3Vao |
|
@ -1,16 +0,0 @@ |
|||||
--- # null block |
|
||||
ver: 0 |
|
||||
data: |
|
||||
seq: -1 |
|
||||
payload: ~ |
|
||||
comment: "This is not a block (null block)" |
|
||||
meta: |
|
||||
seed: 0xb3560762 |
|
||||
salt: 12131054599640746025 # used in address computation |
|
||||
salt: ~ # used in address computation |
|
||||
txroot: ~ |
|
||||
audit: |
|
||||
peerid: Anonymous |
|
||||
tics: 0 |
|
||||
ip: 0.0.0.0 |
|
||||
prev: ~ |
|
@ -0,0 +1,18 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
## Config parameters |
||||
|
|
||||
|
|
||||
|
Important parameter to be updated: |
||||
|
|
||||
|
- genhash |
||||
|
- txcoin |
||||
|
- coinbase public key & signature |
||||
|
|
||||
|
|
||||
|
file : [$SITE/config.yml][1] |
||||
|
|
||||
|
|
||||
|
[1]: /api/v0.0/getcas?dir=.&addr=config |
||||
|
|
@ -0,0 +1,21 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# ToyChain Admin Page |
||||
|
|
||||
|
1. [signup][1] ([keygen][1]) |
||||
|
1. [settings][2] |
||||
|
1. [README][3] |
||||
|
|
||||
|
|
||||
|
## Elliptic Curves Keys |
||||
|
|
||||
|
1. [EC keys][4] |
||||
|
1. [coinbase key][5] |
||||
|
|
||||
|
|
||||
|
[1]: keygen.html |
||||
|
[2]: settings.html |
||||
|
[3]: /README.html |
||||
|
[4]: /api/v0.0/getcas?dir=secrets&addr=keys |
||||
|
[5]: /api/v0.0/getcas?dir=.&addr=registration |
@ -0,0 +1,18 @@ |
|||||
|
const useCapture = true; // capture, bubbling: false
|
||||
|
var elem = document.getElementsByTagName('button')[0]; |
||||
|
elem.addEventListener('click',keygen,useCapture); |
||||
|
|
||||
|
function keygen(ev) { |
||||
|
console.log('keygen: %o',ev) |
||||
|
let name = document.getElementsByTagName('input')[0].value; |
||||
|
let namep = name.replace(/ /g,'+'); |
||||
|
let url = api_url + `keygen?name=${namep}`; |
||||
|
let data = fetch(url).then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
let tarea = document.getElementsByTagName('textarea')[0]; |
||||
|
tarea.innerText = JSON.stringify(obj.identity); |
||||
|
|
||||
|
console.log('keygen.obj.keys:',obj.keys); |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
base: "../" |
||||
|
--- |
||||
|
## Toy-Chain : Key pair Generation |
||||
|
|
||||
|
<input name="name" placeholder="name (optional)"><button>create</button> |
||||
|
|
||||
|
identity: |
||||
|
<textarea> |
||||
|
</textarea> |
||||
|
<!--<button>save</button>--> |
||||
|
|
||||
|
key files: [$SITE/secrets/keys.yml][1] |
||||
|
|
||||
|
<script src="keygen.js"></script> |
||||
|
|
||||
|
|
||||
|
[1]: /api/v0.0/getcas?dir=secrets&addr=keys |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,19 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# manual miner registration |
||||
|
|
||||
|
1. edit [templ/txcoin.yml][1] |
||||
|
{% comment %} |
||||
|
2. run ``signtx.pl templ/txcoin.yml`` |
||||
|
3. view [templ/txcoin.yml.sig][2] |
||||
|
4. update [registration.yml][4] |
||||
|
{%- endcomment -%} |
||||
|
3. run [t/genesis.t][3] |
||||
|
4. verify [registration.yml][4] |
||||
|
|
||||
|
|
||||
|
[1]: /api/v0.0/getyml?f=templ/txcoin.yml |
||||
|
[2]: /api/v0.0/getyml?f=templ/txcoin.yml.sig&encode=json |
||||
|
[3]: /t/genesis.t |
||||
|
[4]: /api/v0.0/getyml?f=registration.yml&encode=json |
@ -0,0 +1,27 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
## ToyChain Settings |
||||
|
|
||||
|
In order to have a functional blockchain you need |
||||
|
|
||||
|
1. [generate][1] a node [keypair][9] (ECDSA for signing transactions) |
||||
|
1. [register][2] as a miner by creating a coinbase transaction |
||||
|
1. create [genesis][3] block |
||||
|
1. update [config][10] file (and restart API) |
||||
|
1. connect to peers on the [network][4] |
||||
|
1. collect transactions from [txpool][5] and validate them |
||||
|
1. [minepool][6] |
||||
|
2. [explore][8] the [chain][7] |
||||
|
|
||||
|
[1]: /admin/keygen.html |
||||
|
[2]: /admin/register.html |
||||
|
[3]: /docs/genesis.html |
||||
|
[4]: /api/nodes.html |
||||
|
[5]: /docs/txpool.html |
||||
|
[6]: /api/minepool.html |
||||
|
[7]: /docs/chain.html |
||||
|
[8]: /api/explore.html |
||||
|
[9]: /api/v0.0/getcas?dir=secrets&addr=keys |
||||
|
[10]: /admin/config.html |
||||
|
[11]: /api/v0.0/getcas?dir=.&addr=config |
@ -0,0 +1,47 @@ |
|||||
|
const useCapture = true; // capture, bubbling: false
|
||||
|
var elem = document.getElementsByTagName('button')[0]; |
||||
|
elem.addEventListener('click',register,useCapture); |
||||
|
|
||||
|
let promises = []; |
||||
|
promises.push( get_config() ); |
||||
|
promises.push( get_keys() ); |
||||
|
|
||||
|
function register(ev) { |
||||
|
console.log('register: %o',ev) |
||||
|
|
||||
|
let name = document.getElementsByName('name')[0].value; |
||||
|
let peerid = document.getElementsByName('peerid')[0].value; |
||||
|
let minerid = document.getElementsByName('minerid')[0].value; |
||||
|
let account = document.getElementsByName('account')[0].value; |
||||
|
let bkreward = document.getElementsByName('bkreward')[0].value; |
||||
|
|
||||
|
let namep = name.replace(/ /g,'+'); |
||||
|
let url = api_url + `register?account=${namep}&bkreward=${bkreward}`; |
||||
|
let data = fetch(url).then(resp => resp.json()); |
||||
|
console.log('register.data:',data); |
||||
|
return data; |
||||
|
} |
||||
|
|
||||
|
Promise.all(promises).then( ar => { |
||||
|
let config = ar[0].config; |
||||
|
let keys = ar[1].data; |
||||
|
console.log('config:',config); |
||||
|
console.log('keys:',keys); |
||||
|
|
||||
|
document.getElementsByName('name')[0].value = keys.identity.name; |
||||
|
document.getElementsByName('peerid')[0].value = keys.identity.public; |
||||
|
document.getElementsByName('minerid')[0].value = keys.miner.public; |
||||
|
document.getElementsByName('account')[0].value = keys.distribution.public; |
||||
|
document.getElementsByName('bkreward')[0].value = config.bkreward; |
||||
|
|
||||
|
}). |
||||
|
catch(console.error); |
||||
|
|
||||
|
function get_config() { |
||||
|
let url = api_url + 'config'; |
||||
|
return fetch(url).then(resp => resp.json()).catch(console.error) |
||||
|
} |
||||
|
function get_keys() { |
||||
|
let url = api_url + 'getcas?dir=secrets&addr=keys'; |
||||
|
return fetch(url).then(resp => resp.json()).catch(console.error) |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
base: "../" |
||||
|
--- |
||||
|
## Toy-Chain : Miner Registration |
||||
|
|
||||
|
name: <input name="name" placeholder="your name"> ([edit][1]) |
||||
|
<br>peerid: <input name="peerid" placeholder="peerid" size=44> |
||||
|
<br>minerid: <input name="minerid" placeholder="minerid" size=44> |
||||
|
<br>account: <input name="account" placeholder="publickey of coinbase destination" size=44> |
||||
|
<br>block reward:<input name="bkreward" placeholder="block reward" size=3> |
||||
|
<br><button>register</button> (not implemented yet: use [manual registration][2]) |
||||
|
|
||||
|
confirmation: |
||||
|
<span id=output></span> |
||||
|
|
||||
|
<script src="register.js"></script> |
||||
|
|
||||
|
|
||||
|
[1]: /admin/keygen.html |
||||
|
[2]: /admin/manual-registration.html |
@ -0,0 +1,19 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
## ToyChain Settings |
||||
|
|
||||
|
In order to have a functional blockchain you need |
||||
|
|
||||
|
1. [generate][1] a node [keypair][2] ([ECDSA] for signing transactions) |
||||
|
1. [register][4] as a miner by creating a coinbase transaction |
||||
|
|
||||
|
|
||||
|
### comming soon : |
||||
|
|
||||
|
1. [new-settings](new-settings.html) |
||||
|
|
||||
|
[1]: /admin/keygen.html |
||||
|
[2]: /api/v0.0/getcas?dir=secrets&addr=keys |
||||
|
[3]: /api/v0.0/getyml?f=secrets/keys.yml&encode=json |
||||
|
[4]: /admin/register.html |
@ -0,0 +1,15 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
api_url: '/api/v0.0/' |
||||
|
--- |
||||
|
## API audit |
||||
|
|
||||
|
This api call allow you to audit the server |
||||
|
|
||||
|
endpoint: '{{page.api_url}}audit' |
||||
|
|
||||
|
|
||||
|
example: [{{page.api_url}}audit]({{page.api_url}}audit) |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,15 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
api_url: '/api/v0.0/' |
||||
|
--- |
||||
|
## API cmd |
||||
|
|
||||
|
This api call allow you to run generic commands on the server |
||||
|
|
||||
|
endpoint: '{{page.api_url}}cmd' |
||||
|
|
||||
|
|
||||
|
example: [{{page.api_url}}cmd/what]({{page.api_url}}cmd/what) |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,22 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
api_url: '/api/v0.0/' |
||||
|
cmd: config |
||||
|
--- |
||||
|
## API {{page.cmd}} |
||||
|
|
||||
|
This api call allow you see the {{page.cmd}} parameters |
||||
|
|
||||
|
endpoint: '{{page.api_url}}{{page.cmd}}' |
||||
|
|
||||
|
example: [{{page.api_url}}{{page.cmd}}]({{page.api_url}}{{page.cmd}}) |
||||
|
|
||||
|
|
||||
|
### Alternative |
||||
|
|
||||
|
you can also get the config.yml file directly: |
||||
|
- [$SITE/config.yml](/api/v0.0/getcas?dir=.&addr=config) |
||||
|
- [$SITE/config.yml](/config.yml) |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,16 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
api_url: '/api/v0.0/' |
||||
|
cmd: env |
||||
|
--- |
||||
|
## API {{page.cmd}} |
||||
|
|
||||
|
This api call allow you to {{page.cmd}} the server |
||||
|
|
||||
|
endpoint: '{{page.api_url}}{{page.cmd}}' |
||||
|
|
||||
|
|
||||
|
example: [{{page.api_url}}{{page.cmd}}]({{page.api_url}}{{page.cmd}}) |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,16 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
api_url: '/api/v0.0/' |
||||
|
cmd: explore |
||||
|
--- |
||||
|
## API {{page.cmd}} |
||||
|
|
||||
|
This api call allow you to {{page.cmd}} the server |
||||
|
|
||||
|
endpoint: '{{page.api_url}}{{page.cmd}}' |
||||
|
|
||||
|
|
||||
|
example: [{{page.api_url}}{{page.cmd}}]({{page.api_url}}{{page.cmd}}) |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,22 @@ |
|||||
|
|
||||
|
var url = api_url + 'getblock' |
||||
|
|
||||
|
var elem = document.getElementsByTagName('div')[0]; |
||||
|
let button = document.getElementsByTagName('button')[0]; |
||||
|
|
||||
|
|
||||
|
|
||||
|
let promised_peerid = fetch(url). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
console.log('peerid.obj:',obj); |
||||
|
let buf = elem.innerHTML; |
||||
|
buf = buf.replace(':peerid',obj.peerid); |
||||
|
buf = buf.replace(':name',obj.name); |
||||
|
elem.innerHTML = buf; |
||||
|
return obj |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
|
||||
|
|
||||
|
console.log('peerid.js loaded'); |
@ -0,0 +1,24 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
api_url: '/api/v0.0/' |
||||
|
cmd: getblock |
||||
|
--- |
||||
|
## API {{page.cmd}} |
||||
|
|
||||
|
This api call allow you to see the content of a block |
||||
|
|
||||
|
endpoint: '{{page.api_url}}{{page.cmd}}' |
||||
|
|
||||
|
|
||||
|
example: [{{page.api_url}}{{page.cmd}}?n=31]({{page.api_url}}{{page.cmd}}?n=31) |
||||
|
|
||||
|
n: <input name="n" type="integer" value="" placeholder="height of the block"> |
||||
|
<br>hash: <input name="hash" type="text" value="" placeholder="hash value of the block"> |
||||
|
<br>addr: <input name="addr" type="text" value="" placeholder="addr of the block content"> |
||||
|
<button>view</button> |
||||
|
|
||||
|
## json: |
||||
|
<textarea></textarea> |
||||
|
|
||||
|
<script src="getblock.js"></script> |
||||
|
|
@ -0,0 +1,51 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
base: "../" |
||||
|
version: 'v0.0' |
||||
|
api_url: '/api/v0.0' |
||||
|
--- |
||||
|
# ToyChain API ({{page.version}}) |
||||
|
|
||||
|
api endpoint : [http://127.0.0.1:8089/api/{{page.version}}/*][1] |
||||
|
|
||||
|
### API development status |
||||
|
|
||||
|
1. [status](/docs/status.html) |
||||
|
2. [chain viewer](/docs/chain.html) |
||||
|
|
||||
|
### available commands : |
||||
|
|
||||
|
* [{{page.api_url}}/audit](audit.html) |
||||
|
* [{{page.api_url}}/cmd](cmd.html) |
||||
|
* [{{page.api_url}}/config](config.html) |
||||
|
* [{{page.api_url}}/env](env.html) |
||||
|
* [{{page.api_url}}/getblock](getblock.html) |
||||
|
* [{{page.api_url}}/getcas](getcas.html) |
||||
|
* [{{page.api_url}}/getchain](getchain.html) |
||||
|
* [{{page.api_url}}/getheads](getheads.html) |
||||
|
* [{{page.api_url}}/getheight](getheight.html) |
||||
|
* [{{page.api_url}}/getpool](getpool.html) |
||||
|
* [{{page.api_url}}/gettx](gettx.html) |
||||
|
* [{{page.api_url}}/mergechain](mergechain.html) |
||||
|
* [{{page.api_url}}/minepool](minepool.html) |
||||
|
* [{{page.api_url}}/peerid](peerid.html) |
||||
|
* [{{page.api_url}}/sendhead](sendhead.html) |
||||
|
* [{{page.api_url}}/setcas](setcas.html) |
||||
|
* [{{page.api_url}}/settx](settx.html) |
||||
|
* [{{page.api_url}}/update](update.html) |
||||
|
* [{{page.api_url}}/version](version.html) |
||||
|
|
||||
|
### CURL commands: |
||||
|
|
||||
|
- example of curl commands: [curl-test-script.sh](/curltest.sh) |
||||
|
|
||||
|
|
||||
|
### Initial steps |
||||
|
|
||||
|
2. [register][2] yourself as a miner (in order to get the coinbase) |
||||
|
1. create the [genesis][3] block |
||||
|
|
||||
|
[1]: /api/version |
||||
|
[2]: /admin/register.html |
||||
|
[3]: /docs/genesis.html |
||||
|
|
@ -0,0 +1,45 @@ |
|||||
|
|
||||
|
|
||||
|
elem = document.getElementsByTagName('table')[0]; |
||||
|
|
||||
|
getnodes(); |
||||
|
async function getnodes() { |
||||
|
let config = await fetch(api_url + 'config'). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { return obj.config }). |
||||
|
catch(console.error); |
||||
|
console.log('nodes.config:',config); |
||||
|
|
||||
|
let n = 1; |
||||
|
let list = '<ul>'; |
||||
|
let nodes = []; |
||||
|
for (node of config.nodes) { |
||||
|
console.log('nodes.node:',node); |
||||
|
let [ip,port] = node.split(':'); |
||||
|
let info = await get_info(node); |
||||
|
nodes.push(info); |
||||
|
let url=`http://${node}`; |
||||
|
let status='offline'; |
||||
|
let info_url = `${url}${api_url}getinfo`; |
||||
|
list += `<li>node${n} (:${port}) <a href="${url}">${node}</a> ${status} <a href="${info_url}">information</a></li>\n`; |
||||
|
console.log('nodes.info:',info); |
||||
|
n++; |
||||
|
} |
||||
|
list += '</ul>'; |
||||
|
let elem = document.getElementById('list'); |
||||
|
elem.innerHTML = list; |
||||
|
return nodes; |
||||
|
} |
||||
|
function get_info(node) { |
||||
|
let [ip,port] = node.split(':'); |
||||
|
let remote_api_url = `http://${node}${api_url}`; |
||||
|
let promised = fetch(remote_api_url + 'getinfo'). |
||||
|
then(resp => resp.json). |
||||
|
then(obj => { let info = obj.info; return info; }). |
||||
|
catch(console.error); |
||||
|
return promised; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
console.log('peerid.js loaded'); |
@ -0,0 +1,31 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# Toy Chain : Peer Networks |
||||
|
|
||||
|
We count :n active [nodes][1] on the *[ToyChain][2] MainNet* . |
||||
|
|
||||
|
|
||||
|
| nodename | port | endpoint | status | information | |
||||
|
|----------|------|----------|--------|-------------| |
||||
|
| :nname | :port | :url | :status | :info | |
||||
|
|
||||
|
<div id=list></div> |
||||
|
|
||||
|
<!-- |
||||
|
<table> |
||||
|
<tr><th>ip</th><th>port</th><th>endpoint</th><th>information</th></tr> |
||||
|
<tr><td>:ip</td><td>:port</td><td>:url</td><td>:info</td></tr> |
||||
|
</table> |
||||
|
--> |
||||
|
|
||||
|
<br>-- |
||||
|
<br><small>by: <span id=sig></span> src: [md],[css],[js]</small> |
||||
|
|
||||
|
<script src="nodes.js"></script> |
||||
|
|
||||
|
[1]: /api/v0.0/getnodes |
||||
|
[2]: /toychain |
||||
|
[md]: nodes.md |
||||
|
[css]: /style.css |
||||
|
[js]: nodes.js |
@ -0,0 +1,20 @@ |
|||||
|
|
||||
|
var url = api_url + 'peerid' |
||||
|
|
||||
|
elem = document.getElementsByTagName('div')[0]; |
||||
|
|
||||
|
|
||||
|
let promised_peerid = fetch(url). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
console.log('peerid.obj:',obj); |
||||
|
let buf = elem.innerHTML; |
||||
|
buf = buf.replace(':peerid',obj.peerid); |
||||
|
buf = buf.replace(':name',obj.name); |
||||
|
elem.innerHTML = buf; |
||||
|
return obj |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
|
||||
|
|
||||
|
console.log('peerid.js loaded'); |
@ -0,0 +1,15 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# API Peerid |
||||
|
|
||||
|
|
||||
|
This page allow you to see your peerid (i.e. node identity) |
||||
|
|
||||
|
``` |
||||
|
your peerid is :peerid; |
||||
|
your name is :name; |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
<script src="peerid.js"></script> |
@ -0,0 +1,53 @@ |
|||||
|
|
||||
|
let button = document.getElementById('submit'); |
||||
|
button.addEventListener('click',createtx,false); |
||||
|
|
||||
|
loadtx('templ/txexample.yml'); |
||||
|
|
||||
|
function createtx() { |
||||
|
|
||||
|
let txyml = document.getElementsByName('tx').value; |
||||
|
|
||||
|
let promised = fetch(api_url + 'settx?',{method:'POST',data}). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
|
||||
|
elem = document.getElementById('json'); |
||||
|
elem.innerText = JSON.stringify(obj); |
||||
|
|
||||
|
let bkcontent = obj.bkcontent; |
||||
|
let txmerkle = bkcontent.txmeta.merkle |
||||
|
if (typeof(txmerkle) != 'undefined') { |
||||
|
let list = '<ul>'; |
||||
|
for (let txa of txmerkle) { |
||||
|
console.log('getblock.txa:',txa); |
||||
|
let tx_url = api_url + `gettx?addr=${txa}` |
||||
|
list += `<li><a href="${tx_url}">${txa}</a></li>` |
||||
|
} |
||||
|
list += '</ul>'; |
||||
|
elem = document.getElementById('list'); |
||||
|
elem.innerHTML = list; |
||||
|
} |
||||
|
|
||||
|
return obj; |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
promised.then(obj => { console.log('obj:',obj); return obj; }); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
function loadtx(f) { |
||||
|
let url = api_url + `getyml?f=${f}`; |
||||
|
let promised = fetch(`/${f}`). |
||||
|
then(resp => resp.text()). |
||||
|
then(yaml => { |
||||
|
document.getElementsByName('tx')[0].value = yaml; |
||||
|
return yaml; |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
} |
||||
|
|
||||
|
// ----------------------------------------------------
|
||||
|
|
||||
|
|
||||
|
console.log('transaction.js loaded'); |
@ -0,0 +1,43 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
## ToyChain Transaction |
||||
|
|
||||
|
|
||||
|
Transactions block is an added record to the block which allow to attached values transfer to the block. |
||||
|
|
||||
|
A transaction descript a transfer of value between account protected via [ECC][1] |
||||
|
(we use [secp256k1][5] see code [ECKeys.pm][2]). |
||||
|
|
||||
|
You can register your [keypair][4] in the [admin](/admin/) section under [signup / keygen][3]. |
||||
|
|
||||
|
A transaction has inputs, outputs, and signatures, |
||||
|
in order be valid |
||||
|
|
||||
|
- the total of inputs must be greater than the total of ouputs |
||||
|
- every account on the input side must have enough balance to satisfy the transactions |
||||
|
- all signature attached to the transaction must be authentic and the signed message not tempered |
||||
|
|
||||
|
example of transaction in ([yaml][6] format) |
||||
|
|
||||
|
<textarea name=tx rows=7></textarea> |
||||
|
{% comment %} |
||||
|
<button id=sign>sign</button> |
||||
|
<button id=validate>validate</button> |
||||
|
{%- endcomment -%} |
||||
|
<button id=submit>submit</button> |
||||
|
|
||||
|
<textarea id=json></textarea> |
||||
|
|
||||
|
txaddr: <span id=txaddr><i>:txaddr</i></span> |
||||
|
|
||||
|
[1]: https://duckduckgo.com?q=Elliptic+Curve+Cryptography |
||||
|
[2]: /lib/ECKeys.pm |
||||
|
[3]: /admin/keygen.html |
||||
|
[4]: /templ/keys.yml |
||||
|
[5]: https://duckduckgo.com?q=secp256k1+!g |
||||
|
[6]: /templ/txexample.yml |
||||
|
|
||||
|
<a href="/docs/txpool.html"><button id=txpool>txpool</button></a> |
||||
|
|
||||
|
<script src="transaction.js"></script> |
@ -0,0 +1,5 @@ |
|||||
|
# |
||||
|
|
||||
|
cat $1 | json_xs -f yaml -t json | tee ${1%.*}.json |
||||
|
echo '' |
||||
|
ls -l ${1%.*}.json |
@ -1,45 +1,29 @@ |
|||||
--- # toychain's config |
--- # toychain's config |
||||
version: 1.12 |
|
||||
|
version: 1.13 |
||||
chain: toychain |
chain: toychain |
||||
apiver: '0.0' |
apiver: '0.0' |
||||
ipfsgw: 8390 |
|
||||
|
|
||||
|
# ------------------------------------------ |
||||
|
# node specifics |
||||
port: 8089 |
port: 8089 |
||||
|
|
||||
|
# ------------------------------------------ |
||||
# p2p network |
# p2p network |
||||
# api = p2p+1 |
# api = p2p+1 |
||||
nodes: |
nodes: |
||||
|
# - 127.0.0.1:8089 |
||||
- 127.0.0.1:8091 |
- 127.0.0.1:8091 |
||||
- 127.0.0.2:8093 |
- 127.0.0.2:8093 |
||||
- 127.0.0.3:8095 |
- 127.0.0.3:8095 |
||||
- 127.0.0.4:8097 |
- 127.0.0.4:8097 |
||||
- 127.0.0.5:8099 |
- 127.0.0.5:8099 |
||||
|
|
||||
|
# ------------------------------------------ |
||||
# block parameters : |
# block parameters : |
||||
bkver: 0 |
bkver: 0 |
||||
bkreward: 100 |
|
||||
coinbase: |
coinbase: |
||||
reward: 50 |
|
||||
public: ZPD9SRTr5ZMx6coZV6NrUxgmVfCkqB55gTdAwJKQVjp7W |
|
||||
signature: ~ |
|
||||
|
|
||||
genhash: Z9BEepHz9jLWzNebDEZTrEKusuU9zomFoaaPxngCQ5D39 |
|
||||
genhash: Z9BEdvJt9F2xeY6BP3gXMvGikFvcUv1kvESQyhSKznLDi |
|
||||
genhash: Z9BEeytxKdWLtGhirNstvvRtJ4273GmVqJ7r2pKmoCR7G |
|
||||
genhash: Z9BEdXmPNa1DkEJKQ1BhuMg7M1nHRD6NLKoXpJ6X84NqK |
|
||||
|
|
||||
nullhash: Z9BEeWD4Mww7yrXyPRXrfM2y6FxsQGfaNPzC8DxWq4ATq |
|
||||
|
|
||||
txgen: Ztxrms5c5oKqb9Zof3xeC5Q2ZQjSaWv7FU4rAxe2s3sP |
|
||||
txgen: ZTxoBj3SNdKGMxXLTdxScnmScN7uCveoM2zPmDoMS4CN |
|
||||
txgen: ZTxGeH4J9oWMci2pcJ7yZ1baMb47i7zd6ihHissKifvQ |
|
||||
|
|
||||
txcoin: ZCBuCkQFRBeiGnANEwb65TZptSTUpm62WYS4Xj9gkMLU |
|
||||
txcoin: ZCBtx9SS9n57R2cx3AAuRDKJ4b9WsWA5MoTVEtxGQAdV |
|
||||
txcoin: ZCBtx7Wg59hvMogWDchKVcGUMo68qDe2dkRfzaskAh3G |
|
||||
|
|
||||
|
reward: 100 |
||||
|
|
||||
# Proof of Work option |
# Proof of Work option |
||||
difficulty: 5 |
difficulty: 5 |
||||
maxdiff: 7 |
maxdiff: 7 |
||||
# CAstore options |
|
||||
trackmode: 1 |
|
||||
|
# ------------------------------------------ |
@ -1,23 +0,0 @@ |
|||||
--- # toychain's config |
|
||||
version: 1.06 |
|
||||
chain: toychain |
|
||||
apiver: '0.0' |
|
||||
ipfsgw: 8390 |
|
||||
port: 8089 |
|
||||
|
|
||||
# p2p network = api+1 |
|
||||
apis: |
|
||||
- 127.0.0.1:8091 |
|
||||
- 127.0.0.2:8093 |
|
||||
- 127.0.0.3:8095 |
|
||||
- 127.0.0.4:8097 |
|
||||
- 127.0.0.5:8099 |
|
||||
|
|
||||
# block parameters : |
|
||||
bkver: 0 |
|
||||
bkreward: 100 |
|
||||
# Proof of Work option |
|
||||
difficulty: 5 |
|
||||
maxdiff: 7 |
|
||||
# CAstore options |
|
||||
trackmode: 1 |
|
@ -0,0 +1,10 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# Unspend TXO |
||||
|
|
||||
|
The unspend transaction outputs are defining the (mutable) state of the blockchain, |
||||
|
we choose to aggregate them per addresses such that we only have to store the balance of addresses which |
||||
|
have a positive balance; rather than maintaning a complete list of unspend transactions. |
||||
|
|
||||
|
- [UTXO](/api/v0.0/getjson?obj=TXPOOL::UTXO) |
@ -0,0 +1,111 @@ |
|||||
|
|
||||
|
let button = document.getElementsByTagName('button')[0]; |
||||
|
button.addEventListener('click',getblock,false); |
||||
|
|
||||
|
|
||||
|
function getblock() { |
||||
|
|
||||
|
let n = document.getElementsByName('n').value; |
||||
|
let hash = document.getElementsByName('hash').value; |
||||
|
let addr = document.getElementsByName('addr').value; |
||||
|
let query = []; |
||||
|
if (n != '') { |
||||
|
query.push(`n=${n}`) |
||||
|
} else if (hash != '') { |
||||
|
query.push(`hash=${hash}`) |
||||
|
} else if (addr != '') { |
||||
|
query.push(`addr=${addr}`) |
||||
|
} |
||||
|
|
||||
|
document.getElementById('comment').innerText = ''; |
||||
|
let promised = fetch(api_url + 'getblock?' + query.join('&')). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
let elem; |
||||
|
let payload_value = obj.bkcontent.data.payload; |
||||
|
let payload_url = `/api/getblock?addr=${obj.bkaddr}` |
||||
|
if (payload_value.match('/ipfs/')) { |
||||
|
payload_url = 'https://ipfs.blockringtm.ml'+ payload_value |
||||
|
} else if (payload_value.match('/https?:|\.htm/')) { |
||||
|
payload_url = payload_value; |
||||
|
} |
||||
|
let payload_link = `<a href="${payload_url}">${payload_value}</a>`; |
||||
|
|
||||
|
document.getElementsByName('hash')[0].value = obj.bkhash; |
||||
|
document.getElementsByName('addr')[0].value = obj.bkaddr; |
||||
|
document.getElementById('prev').innerHTML = `<a href="/api/v0.0/getblock?hash=${obj.bkprev}">${obj.bkprev}</a>`; |
||||
|
document.getElementById('seq').innerText = obj.bkcontent.data.seq; |
||||
|
document.getElementById('payload').innerHTML = payload_link; |
||||
|
document.getElementById('comment').innerText = obj.bkcontent.data.comment; |
||||
|
document.getElementById('txroot').innerText = obj.bkcontent.meta.txroot || '?'; |
||||
|
document.getElementById('hash').innerText = obj.bkhash |
||||
|
document.getElementById('pow').innerText = obj.pow |
||||
|
document.getElementById('api').innerHTML = `(<a href="/api/v0.0/getblock?hash=${obj.bkhash}">json</a>)`; |
||||
|
|
||||
|
elem = document.getElementById('json'); |
||||
|
elem.innerText = JSON.stringify(obj); |
||||
|
|
||||
|
let bkcontent = obj.bkcontent; |
||||
|
let txmerkle = bkcontent.txmeta.merkle |
||||
|
if (typeof(txmerkle) != 'undefined') { |
||||
|
let list = '<ul>'; |
||||
|
for (let txa of txmerkle) { |
||||
|
console.log('getblock.txa:',txa); |
||||
|
let tx_url = api_url + `gettx?addr=${txa}` |
||||
|
list += `<li><a href="${tx_url}">${txa}</a></li>` |
||||
|
} |
||||
|
list += '</ul>'; |
||||
|
elem = document.getElementById('list'); |
||||
|
elem.innerHTML = list; |
||||
|
} |
||||
|
|
||||
|
return obj; |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
promised.then(obj => { console.log('obj:',obj); return obj; }); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
// ----------------------------------------------------
|
||||
|
|
||||
|
async function getnodes() { |
||||
|
let config = await fetch(api_url + 'config'). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { return obj.config }). |
||||
|
catch(console.error); |
||||
|
console.log('nodes.config:',config); |
||||
|
|
||||
|
let n = 1; |
||||
|
let list = '<ul>'; |
||||
|
let nodes = []; |
||||
|
for (node of config.nodes) { |
||||
|
console.log('nodes.node:',node); |
||||
|
let [ip,port] = node.split(':'); |
||||
|
let info = await get_info(node); |
||||
|
nodes.push(info); |
||||
|
let url=`http://${node}`; |
||||
|
let status='offline'; |
||||
|
let info_url = `${url}${api_url}getinfo`; |
||||
|
list += `<li>node${n} (:${port}) <a href="${url}">${node}</a> ${status} <a href="${info_url}">information</a></li>\n`; |
||||
|
console.log('nodes.info:',info); |
||||
|
n++; |
||||
|
} |
||||
|
list += '</ul>'; |
||||
|
let elem = document.getElementById('list'); |
||||
|
elem.innerHTML = list; |
||||
|
return nodes; |
||||
|
} |
||||
|
function get_info(node) { |
||||
|
let [ip,port] = node.split(':'); |
||||
|
let remote_api_url = `http://${node}${api_url}`; |
||||
|
let promised = fetch(remote_api_url + 'getinfo'). |
||||
|
then(resp => resp.json). |
||||
|
then(obj => { let info = obj.info; return info; }). |
||||
|
catch(console.error); |
||||
|
return promised; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
console.log('heads.js loaded'); |
@ -0,0 +1,39 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# ToyChain's Block |
||||
|
|
||||
|
A block in ToyChain blockchain is 80 bytes |
||||
|
|
||||
|
n: <input name=n size=3> <span id=comment></span> |
||||
|
<br>hash: <input name=hash size=43> |
||||
|
<br>addr: <input name=addr size=43> |
||||
|
<br>prev: <span id=prev><i>:prev</i></span> |
||||
|
<br><button>fetch</button> |
||||
|
|
||||
|
<textarea id=json></textarea> |
||||
|
|
||||
|
Here is the content of the requested block <span id=api></span> |
||||
|
|
||||
|
- seq: <span id=seq>#.</span> |
||||
|
payload : "<span id=payload><i>:payload</i></span>" |
||||
|
- hash: <span id=hash><i>:hash</i></span> |
||||
|
pow: <span id=pow><i>:pow</i></span> |
||||
|
- txroot: <span id=txroot><i>:txroot</i></span> |
||||
|
|
||||
|
<div id=content></div> |
||||
|
|
||||
|
List of attached transactions : |
||||
|
|
||||
|
<div id=list></div> |
||||
|
|
||||
|
|
||||
|
|
||||
|
<script src="block.js"></script> |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,30 @@ |
|||||
|
|
||||
|
|
||||
|
getchain(); |
||||
|
function getchain() { |
||||
|
let promised = fetch(api_url + 'getchain'). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
let elem = document.getElementById('json'); |
||||
|
elem.innerText = JSON.stringify(obj); |
||||
|
|
||||
|
let list = '<pre>'; |
||||
|
for (let bh of obj.chain) { |
||||
|
console.log('getchain.bh:',bh); |
||||
|
let blk_url = api_url + `getblock?hash=${bh}`; |
||||
|
list += `<a href="${blk_url}">${bh}</a>\n` |
||||
|
} |
||||
|
list += '</pre>'; |
||||
|
elem = document.getElementById('list'); |
||||
|
elem.innerHTML = list; |
||||
|
|
||||
|
return obj; |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
promised.then(obj => { console.log('obj:',obj); return obj; }); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// ----------------------------------------------------
|
||||
|
console.log('chain.js loaded'); |
||||
|
|
@ -0,0 +1,22 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# ToyChain's Chain View |
||||
|
|
||||
|
The ToyChain blockchain is a list of basic 80 Bytes blocks, |
||||
|
each block is address with a base58 encoded hash of 32B |
||||
|
(i.e. ``32 * l(235) / l(58) = ~44 char.``). |
||||
|
|
||||
|
<textarea id=json></textarea> |
||||
|
|
||||
|
Here is the list all the blocks in the chain |
||||
|
|
||||
|
<div id=list></div> |
||||
|
|
||||
|
See also [HEADs][1] |
||||
|
|
||||
|
<script src="chain.js"></script> |
||||
|
|
||||
|
[1]: /docs/heads.html |
||||
|
|
||||
|
|
@ -0,0 +1,23 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# block difficulties |
||||
|
|
||||
|
we use [hashcash][1] as a mechanism to protect the blockchain from a Sybil Attack. |
||||
|
|
||||
|
The difficulty is the number of hexadecimal digit we have to "resolve" in the block hash. |
||||
|
|
||||
|
Finding a block hash than match the required difficuly is the "work" |
||||
|
and the hash itself is the [*proof of work*][1]. |
||||
|
|
||||
|
example: block [Z9Pa9kcag3TBc6EX671u6Zwk7N6M7jTuQ5HPtjzDrpx4f][2] has is matching a difficulty of 4 |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
[1]: /docs/pow.html |
||||
|
[2]: /api/0.0/getblock?hash=Z9Pa9kcag3TBc6EX671u6Zwk7N6M7jTuQ5HPtjzDrpx4f |
@ -0,0 +1,27 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# Toy Chain Explorer |
||||
|
|
||||
|
The API server has an [explore][1] endpoint that allows to view all of the chain's "[internals][2]" |
||||
|
|
||||
|
You can explore the chain, blocks, transaction and more ... |
||||
|
|
||||
|
- get the [HEADs][3] |
||||
|
- get the [chain][4] |
||||
|
- get a [block][5] |
||||
|
- get the [txpool][6] |
||||
|
- get the [utxo][7] state |
||||
|
- get a [transaction][8] |
||||
|
- get [nodes][9] |
||||
|
|
||||
|
[1]: /api/explore.html |
||||
|
[2]: /docs/internals.html |
||||
|
|
||||
|
[3]: /docs/heads.html |
||||
|
[4]: /docs/chain.html |
||||
|
[5]: /docs/block.html |
||||
|
[6]: /docs/txpool.html |
||||
|
[7]: /docs/utxo.html |
||||
|
[8]: /docs/transactions.html |
||||
|
[9]: /docs/nodes.html |
@ -0,0 +1,57 @@ |
|||||
|
const useCapture = false; // capture, bubbling: false
|
||||
|
|
||||
|
button = document.getElementsByTagName('button')[0]; |
||||
|
button.addEventListener('click',genesis,false); |
||||
|
console.log(button) |
||||
|
var payload = 'QmVnvdASdT1c9fJ2mcDhTAYhb63gcFRkiRmJW7NAm1YcSf'; |
||||
|
//var txcoinhash = 'ZCBtx7Wg59hvMogWDchKVcGUMo68qDe2dkRfzaskAh3G';
|
||||
|
//var prevhash = 'Z9BEeWD4Mww7yrXyPRXrfM2y6FxsQGfaNPzC8DxWq4ATq';
|
||||
|
var pow = '11501558695957493006'; |
||||
|
var comment = 'Genesis ~ Manuela J. Savina'; |
||||
|
|
||||
|
// get default values (from nodes) ...
|
||||
|
let promised_config = fetch(api_url + 'config'). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { return obj.config }). |
||||
|
catch(console.error) |
||||
|
|
||||
|
let promised_nullhash = fetch(api_url + 'getjson?obj=Genesis::nullhash'). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { console.log('promised_nullhash.obj:',obj) |
||||
|
return obj; |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
|
||||
|
Promise.all([promised_config, promised_nullhash]).then( _ => { |
||||
|
let [config,nullhash] = _; |
||||
|
console.log('genesis.config:',config); |
||||
|
document.getElementsByName('payload')[0].value = payload; |
||||
|
document.getElementsByName('txcoinhash')[0].value = config.txcoin; |
||||
|
document.getElementsByName('prevhash')[0].value = nullhash; |
||||
|
document.getElementsByName('pow')[0].value = pow; |
||||
|
document.getElementsByName('comment')[0].value = comment; |
||||
|
}).catch(console.error); |
||||
|
|
||||
|
|
||||
|
function genesis(ev) { |
||||
|
console.log('genesis.ev: %o',ev); |
||||
|
let query = { |
||||
|
"payload": document.getElementsByName('payload')[0].value, |
||||
|
"txcoin": document.getElementsByName('txcoinhash')[0].value, |
||||
|
"bkprev": document.getElementsByName('prevhash')[0].value, |
||||
|
"pow": document.getElementsByName('pow')[0].value, |
||||
|
"comment": document.getElementsByName('comment')[0].value |
||||
|
}; |
||||
|
query_string = Object.keys(query).map( k => k +'='+ query[k] ).join('&'); |
||||
|
let url = api_url + `creategen?${query_string}`; |
||||
|
document.getElementByName('pow')[0].value = 'working...'; |
||||
|
let promised = fetch(url). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
console.log('genesis.obj:',obj); |
||||
|
document.getElementsByName('pow')[0].value = obj.pow; |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
} |
||||
|
|
||||
|
|
@ -0,0 +1,27 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# ToyChain Genesis Block |
||||
|
|
||||
|
The genesis block is a regular block with |
||||
|
only one [coinbase][1] transaction |
||||
|
and a previous link that point to the [NullBlock][3] |
||||
|
|
||||
|
|
||||
|
A block is consist of the following part : |
||||
|
|
||||
|
1. a payload <input name=payload> |
||||
|
2. a [coinbase][2] transaction <input name=txcoinhash> |
||||
|
<!--2. a transactions list (merkle tree) <input name=txpool disabled> --> |
||||
|
3. a link to the previous block <input name=prevhash disabled> |
||||
|
4. a proof of work <input name=pow> |
||||
|
5. an optional comment <input name=comment> |
||||
|
|
||||
|
<button>create</button> |
||||
|
|
||||
|
|
||||
|
[1]: /docs/coinbase.html |
||||
|
[2]: /api/v0.0/getyml?f=templ/txcoin.yml&encode=json |
||||
|
[3]: /api/v0.0/getcas?addr=nullblock&dir=templ |
||||
|
|
||||
|
<script src="genesis.js"></script> |
@ -0,0 +1,74 @@ |
|||||
|
|
||||
|
|
||||
|
getheads(); |
||||
|
function getheads() { |
||||
|
let promised = fetch(api_url + 'getheads'). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
let elem = document.getElementById('json'); |
||||
|
elem.innerText = JSON.stringify(obj); |
||||
|
|
||||
|
let list = '<ul>'; |
||||
|
for (let b of obj.HEADs) { |
||||
|
console.log('getheads.b:',b); |
||||
|
let blk_url = api_url + `getblock?hash=${b.bkhash}`; |
||||
|
let content_url = api_url + `getblock?addr=${b.bkaddr}`; |
||||
|
let peerid = b.bkcontent.audit.peerid; |
||||
|
let whois_url = api_url + `whois?pub=${peerid}` |
||||
|
list += `<li><a href="${blk_url}">${b.bkhash}</a> by <a href="${whois_url}">${peerid}</a>: `+ |
||||
|
`<a href="${content_url}">${b.bkaddr}</a> ${b.bkprev} pow:${b.pow}</li>`; |
||||
|
} |
||||
|
list += '</ul>'; |
||||
|
elem = document.getElementById('list'); |
||||
|
elem.innerHTML = list; |
||||
|
|
||||
|
return obj; |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
promised.then(obj => { console.log('obj:',obj); return obj; }); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
// ----------------------------------------------------
|
||||
|
|
||||
|
async function getnodes() { |
||||
|
let config = await fetch(api_url + 'config'). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { return obj.config }). |
||||
|
catch(console.error); |
||||
|
console.log('nodes.config:',config); |
||||
|
|
||||
|
let n = 1; |
||||
|
let list = '<ul>'; |
||||
|
let nodes = []; |
||||
|
for (node of config.nodes) { |
||||
|
console.log('nodes.node:',node); |
||||
|
let [ip,port] = node.split(':'); |
||||
|
let info = await get_info(node); |
||||
|
nodes.push(info); |
||||
|
let url=`http://${node}`; |
||||
|
let status='offline'; |
||||
|
let info_url = `${url}${api_url}getinfo`; |
||||
|
list += `<li>node${n} (:${port}) <a href="${url}">${node}</a> ${status} <a href="${info_url}">information</a></li>\n`; |
||||
|
console.log('nodes.info:',info); |
||||
|
n++; |
||||
|
} |
||||
|
list += '</ul>'; |
||||
|
let elem = document.getElementById('list'); |
||||
|
elem.innerHTML = list; |
||||
|
return nodes; |
||||
|
} |
||||
|
function get_info(node) { |
||||
|
let [ip,port] = node.split(':'); |
||||
|
let remote_api_url = `http://${node}${api_url}`; |
||||
|
let promised = fetch(remote_api_url + 'getinfo'). |
||||
|
then(resp => resp.json). |
||||
|
then(obj => { let info = obj.info; return info; }). |
||||
|
catch(console.error); |
||||
|
return promised; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
console.log('heads.js loaded'); |
@ -0,0 +1,23 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# ToyChain's HEADs |
||||
|
|
||||
|
The ToyChain blockchain as many as head as there are nodes that holds differents forks. |
||||
|
|
||||
|
<textarea id=json></textarea> |
||||
|
|
||||
|
Here is the list with their respective owners |
||||
|
|
||||
|
<div id=list></div> |
||||
|
|
||||
|
|
||||
|
|
||||
|
<script src="heads.js"></script> |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,44 @@ |
|||||
|
|
||||
|
// getting node information ...
|
||||
|
|
||||
|
info(); |
||||
|
function info() { |
||||
|
let promised = fetch(api_url + 'getinfo'). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
document.getElementById('json').innerText = JSON.stringify(obj.info); |
||||
|
|
||||
|
let p = document.getElementsByTagName('p')[0]; |
||||
|
let buf = p.innerHTML; |
||||
|
buf = buf.replace(':nodeid',obj.info.nodeid); |
||||
|
buf = buf.replace(':port',obj.info.port); |
||||
|
buf = buf.replace(':botname',obj.info.botname); |
||||
|
buf = buf.replace(':owner',obj.info.owner); |
||||
|
buf = buf.replace(':peerid',obj.info.peerid); |
||||
|
buf = buf.replace(':height',obj.info.height); |
||||
|
buf = buf.replace(/:head/g,obj.info.head); |
||||
|
buf = buf.replace(/:genesis/g,obj.info.genesis); |
||||
|
|
||||
|
p.innerHTML = buf; |
||||
|
|
||||
|
if (typeof(obj.api) != 'undefined') { |
||||
|
let list = '<ol>'; |
||||
|
for (let item of obj.api) { |
||||
|
console.log('test.item:',item); |
||||
|
let url = api_url + `getcas?addr=${item}`; |
||||
|
list += `<li><a href="${url}">${item}</a></li>\n` |
||||
|
} |
||||
|
list += '</ol>'; |
||||
|
document.getElementById('list').innerHTML = list; |
||||
|
} |
||||
|
|
||||
|
return obj; |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
promised.then(obj => { console.log('obj:',obj); return obj; }); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// ----------------------------------------------------
|
||||
|
console.log('info.js loaded'); |
||||
|
|
@ -0,0 +1,29 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# Nodes' Information |
||||
|
|
||||
|
<p> |
||||
|
nodeid: :nodeid |
||||
|
<br>port: :port |
||||
|
<br>botname: :botname |
||||
|
<br>owner: :owner |
||||
|
<br>peerid: :peerid |
||||
|
<br> |
||||
|
<br>block height: :height |
||||
|
<br>head bkhash: <a href="/api/v0.0/getblock?hash=:head">:head</a> |
||||
|
<br>genesis bkhash: <a href="/api/v0.0/getblock?hash=:genesis">:genesis</a> |
||||
|
</p> |
||||
|
|
||||
|
|
||||
|
<textarea id=json></textarea> |
||||
|
([json](/api/0.0/getjson?obj=result)) |
||||
|
|
||||
|
<div id=list></div> |
||||
|
|
||||
|
<a href="/docs/"><button id=docs>documentation</button></a> |
||||
|
|
||||
|
<script src="info.js"></script> |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,30 @@ |
|||||
|
|
||||
|
|
||||
|
minepool(); |
||||
|
function minepool() { |
||||
|
let promised = fetch(api_url + 'minepool'). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
document.getElementById('json').innerText = JSON.stringify(obj); |
||||
|
|
||||
|
if (typeof(obj.txpool) != 'undefined') { |
||||
|
let list = '<ol>'; |
||||
|
for (let txa of obj.txpool) { |
||||
|
console.log('getpool.bh:',txa); |
||||
|
let tx_url = api_url + `gettx?addr=${txa}`; |
||||
|
list += `<li><a href="${tx_url}">${txa}</a></li>\n` |
||||
|
} |
||||
|
list += '</ol>'; |
||||
|
document.getElementById('list').innerHTML = list; |
||||
|
} |
||||
|
|
||||
|
return obj; |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
promised.then(obj => { console.log('obj:',obj); return obj; }); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// ----------------------------------------------------
|
||||
|
console.log('txpool.js loaded'); |
||||
|
|
@ -0,0 +1,30 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# ToyChain's Mining |
||||
|
|
||||
|
The ToyChain Mining is the action of |
||||
|
|
||||
|
- creating a new block to record transaction in the [txpool](txpool.html) |
||||
|
- attaching the block to the [HEAD](heads.html) of the chain. |
||||
|
- computing the hash of this block with enough [PoW](pow.html) |
||||
|
- advertizing the new head of the chain |
||||
|
|
||||
|
height: <span id=height></span> |
||||
|
HEAD: <span id=head></span> |
||||
|
new block: <span id=new></span> |
||||
|
|
||||
|
|
||||
|
<textarea id=json></textarea> |
||||
|
([json][1]) |
||||
|
|
||||
|
<div id=list></div> |
||||
|
|
||||
|
<a href="/docs/chain.html"><button id=chain>chain view</button></a> |
||||
|
|
||||
|
|
||||
|
<script src="minepool.js"></script> |
||||
|
|
||||
|
|
||||
|
[1]: /api/0.0/getjson?obj=result |
||||
|
|
@ -0,0 +1,24 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# ToyChain's Mining |
||||
|
|
||||
|
The ToyChain Mining is the action of |
||||
|
|
||||
|
- creating a new block to record transaction in the [txpool](txpool.html) |
||||
|
- attaching the block to the [HEAD](heads.html) of the chain. |
||||
|
- computing the hash of this block with enough [PoW](pow.html) |
||||
|
- advertizing the new head of the chain |
||||
|
|
||||
|
|
||||
|
<textarea id=json></textarea> |
||||
|
|
||||
|
<div id=list></div> |
||||
|
|
||||
|
<a href="/docs/chain.html"><button id=chain>chain view</button></a> |
||||
|
|
||||
|
|
||||
|
<script src="mining.js"></script> |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,30 @@ |
|||||
|
|
||||
|
|
||||
|
getnodes(); |
||||
|
function getnodes() { |
||||
|
let promised = fetch(api_url + 'getnodes'). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
document.getElementById('json').innerText = JSON.stringify(obj.api); |
||||
|
|
||||
|
if (typeof(obj.api) != 'undefined') { |
||||
|
let list = '<ol>'; |
||||
|
for (let node of obj.api) { |
||||
|
console.log('getnodes.node:',node); |
||||
|
let url = `http:/${node}/docs/chain.html` |
||||
|
list += `<li><a href="${url}">${node}</a></li>\n` |
||||
|
} |
||||
|
list += '</ol>'; |
||||
|
document.getElementById('list').innerHTML = list; |
||||
|
} |
||||
|
|
||||
|
return obj; |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
promised.then(obj => { console.log('obj:',obj); return obj; }); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// ----------------------------------------------------
|
||||
|
console.log('nodes.js loaded'); |
||||
|
|
@ -0,0 +1,21 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# ToyChain Nodes |
||||
|
|
||||
|
getting nodes list : fixed network here (no discovery). |
||||
|
|
||||
|
<textarea id=json></textarea> |
||||
|
|
||||
|
<div id=list></div> |
||||
|
> <a href="javascript:location.href=location.origin+'/docs/chain.html';">this node</a> |
||||
|
|
||||
|
|
||||
|
### API commands |
||||
|
|
||||
|
- [/api/v0.0/getnodes](/api/v0.0/getnodes) |
||||
|
|
||||
|
<script src="nodes.js"></script> |
||||
|
|
||||
|
<a href="/docs/"><button id=docs>documentation</button></a> |
||||
|
|
@ -0,0 +1,27 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# API implementation status ... |
||||
|
|
||||
|
### currently available |
||||
|
|
||||
|
- [heads](/docs/heads.html) |
||||
|
- [chain](/docs/chain.html) |
||||
|
- [block](/docs/block.html) |
||||
|
- [transaction](/docs/transactions.html) |
||||
|
- [txpool](/docs/txpool.html) |
||||
|
|
||||
|
### api commands |
||||
|
|
||||
|
- [utxo](/api/utxo.html) |
||||
|
- [gettx](/api/gettx.html) |
||||
|
- [settx](/api/settx.html) |
||||
|
|
||||
|
|
||||
|
### coming soon |
||||
|
|
||||
|
- [UTXO](/docs/UTXO.html) |
||||
|
- [explore](/api/explore.html) |
||||
|
- [internals](/docs/internals.html) |
||||
|
- [register](/admin/register.html) |
||||
|
- [genesis](/docs/genesis.html) |
@ -0,0 +1,30 @@ |
|||||
|
|
||||
|
|
||||
|
testing(); |
||||
|
function testing() { |
||||
|
let promised = fetch(api_url + 'getnodes'). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
document.getElementById('json').innerText = JSON.stringify(obj.api); |
||||
|
|
||||
|
if (typeof(obj.api) != 'undefined') { |
||||
|
let list = '<ol>'; |
||||
|
for (let item of obj.api) { |
||||
|
console.log('test.item:',item); |
||||
|
let url = api_url + `getcas?addr=${item}`; |
||||
|
list += `<li><a href="${url}">${item}</a></li>\n` |
||||
|
} |
||||
|
list += '</ol>'; |
||||
|
document.getElementById('list').innerHTML = list; |
||||
|
} |
||||
|
|
||||
|
return obj; |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
promised.then(obj => { console.log('obj:',obj); return obj; }); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// ----------------------------------------------------
|
||||
|
console.log('txpool.js loaded'); |
||||
|
|
@ -0,0 +1,42 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# Testing the ToyChain |
||||
|
|
||||
|
testing the API ... |
||||
|
|
||||
|
### internals |
||||
|
|
||||
|
- [getnodes](/api/v0.0/getnodes) |
||||
|
- [chain](/api/v0.0/getjson?obj=toychain::chain) |
||||
|
- [TXPOOL](/api/v0.0/getjson?obj=TXPOOL::TXPOOL) |
||||
|
- [UTXO](/api/v0.0/getjson?obj=TXPOOL::UTXO) |
||||
|
- [getregs](/api/v0.0/getjson?obj=registration) |
||||
|
- [getruntime](/api/v0.0/getjson?obj=runtime) |
||||
|
- [txcoin](/api/v0.0/getjson?obj=Genesis::txcoin) |
||||
|
- [getnick](/api/v0.0/getjson?obj=nicknames) |
||||
|
- [getkeys](/api/v0.0/getjson?obj=keys) |
||||
|
|
||||
|
### source : |
||||
|
|
||||
|
- [config](/lib/config.pm) |
||||
|
- [toychain](/lib/toychain.pm) |
||||
|
- [Chain](/lib/Chain.pm) |
||||
|
- [ECKeys](/lib/ECKeys.pm) |
||||
|
- [Genesis](/lib/Genesis.pm) |
||||
|
- [API](/lib/API.pm) |
||||
|
|
||||
|
|
||||
|
### nodes : |
||||
|
|
||||
|
<div id=list></div> |
||||
|
|
||||
|
<textarea id=json></textarea> |
||||
|
|
||||
|
<a href="/docs/"><button id=docs>documentation</button></a> |
||||
|
|
||||
|
|
||||
|
<script src="test.js"></script> |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,51 @@ |
|||||
|
|
||||
|
let button = document.getElementsByTagName('button')[0]; |
||||
|
button.addEventListener('click',gettx,false); |
||||
|
|
||||
|
|
||||
|
function gettx() { |
||||
|
|
||||
|
let addr = document.getElementsByName('addr')[0].value; |
||||
|
let url = api_url + 'gettx?addr=' + addr; |
||||
|
document.getElementById('url').innerHTML = `<a href=${url}>${url}</a>`; |
||||
|
|
||||
|
let promised = fetch(url). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
let elem = document.getElementById('json'); |
||||
|
elem.innerText = JSON.stringify(obj.tx); |
||||
|
|
||||
|
console.log('obj.tx',obj.tx); |
||||
|
document.getElementById('txroot').innerText = obj.tx.txroot |
||||
|
document.getElementById('pow').innerText = obj.tx.pow |
||||
|
|
||||
|
let list = '' |
||||
|
for (let i of obj.tx.inputs) { |
||||
|
public = Object.keys(i)[0]; |
||||
|
list += `<li>${public} ${i[public]}</li>`; |
||||
|
} |
||||
|
document.getElementById('in').innerHTML = list; |
||||
|
list = '' |
||||
|
for (let o of obj.tx.outputs) { |
||||
|
public = Object.keys(o)[0]; |
||||
|
list += `<li>${public} ${o[public]}</li>`; |
||||
|
} |
||||
|
document.getElementById('out').innerHTML = list; |
||||
|
list = '' |
||||
|
for (let s of obj.tx.signatures) { |
||||
|
public = Object.keys(s)[0]; |
||||
|
list += `<li>${public} ${s[public][0]}</li>`; |
||||
|
} |
||||
|
document.getElementById('sig').innerHTML = list; |
||||
|
|
||||
|
document.getElementById('yaml').innerText = obj.yaml; |
||||
|
return obj; |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
promised.then(obj => { console.log('obj:',obj); return obj.tx; }); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
// ----------------------------------------------------
|
||||
|
console.log('transactions.js loaded'); |
@ -0,0 +1,46 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# Transactions |
||||
|
|
||||
|
|
||||
|
There are two types: |
||||
|
|
||||
|
1. mempool transactions : pending validation |
||||
|
2. block transactions : confirmed transactions (organized in merkle tree) |
||||
|
|
||||
|
You can create a [transaction][1] using the [settx][2] [API][3] call. |
||||
|
|
||||
|
You can view transactions with the address : |
||||
|
|
||||
|
addr: <input name=addr size=38 value="ZtxZojTad7bmjVKH67eeRGeaEKkTNQtEdiTxEMKFXGbC"> |
||||
|
<button>view</button> |
||||
|
|
||||
|
<textarea id=json></textarea> |
||||
|
|
||||
|
txroot: <span id=txroot></span> |
||||
|
<br>pow: <span id=pow></span> |
||||
|
<br>url: <span id=url></span> |
||||
|
|
||||
|
### inputs |
||||
|
|
||||
|
<ol id=in></ol> |
||||
|
|
||||
|
### outputs |
||||
|
|
||||
|
<ol id=out></ol> |
||||
|
|
||||
|
### signatures |
||||
|
|
||||
|
<ol id=sig></ol> |
||||
|
|
||||
|
---- |
||||
|
|
||||
|
<pre id=yaml></pre> |
||||
|
|
||||
|
|
||||
|
[1]: /api/transaction.html |
||||
|
[2]: /api/settx.html |
||||
|
[3]: /api/ |
||||
|
|
||||
|
<script src="transactions.js"></script> |
@ -0,0 +1,28 @@ |
|||||
|
|
||||
|
|
||||
|
getpool(); |
||||
|
function getpool() { |
||||
|
let promised = fetch(api_url + 'getpool'). |
||||
|
then(resp => resp.json()). |
||||
|
then(obj => { |
||||
|
document.getElementById('json').innerText = JSON.stringify(obj); |
||||
|
|
||||
|
let list = '<ol>'; |
||||
|
for (let txa of obj.txpool) { |
||||
|
console.log('getpool.bh:',txa); |
||||
|
let tx_url = api_url + `gettx?addr=${txa}`; |
||||
|
list += `<li><a href="${tx_url}">${txa}</a></li>\n` |
||||
|
} |
||||
|
list += '</ol>'; |
||||
|
document.getElementById('list').innerHTML = list; |
||||
|
|
||||
|
return obj; |
||||
|
}). |
||||
|
catch(console.error); |
||||
|
promised.then(obj => { console.log('obj:',obj); return obj; }); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// ----------------------------------------------------
|
||||
|
console.log('txpool.js loaded'); |
||||
|
|
@ -0,0 +1,21 @@ |
|||||
|
--- |
||||
|
layout: simple |
||||
|
--- |
||||
|
# ToyChain's TxPool View |
||||
|
|
||||
|
The ToyChain [TxPool][1] is a list of pending transactions |
||||
|
|
||||
|
<textarea id=json></textarea> |
||||
|
|
||||
|
Here is the list all the transactions in the pool |
||||
|
|
||||
|
<div id=list></div> |
||||
|
|
||||
|
<a href="/docs/minepool.html"><button id=minepool>minepool</button></a> |
||||
|
|
||||
|
|
||||
|
<script src="txpool.js"></script> |
||||
|
|
||||
|
[1]: /api/v0.0/getjson?obj=TXPOOL::TXPOOL |
||||
|
|
||||
|
|
@ -1,32 +0,0 @@ |
|||||
#!/usr/bin/perl |
|
||||
# |
|
||||
# testing out ecdsa key generation ... |
|
||||
|
|
||||
use Crypt::PK::ECC; |
|
||||
use YAML::Syck qw(Dump); |
|
||||
|
|
||||
#Key generation |
|
||||
my $pk = Crypt::PK::ECC->new(); |
|
||||
$pk->generate_key('secp256k1'); |
|
||||
my $private_der = $pk->export_key_der('private'); |
|
||||
|
|
||||
my $public_pem = $pk->export_key_pem('public'); |
|
||||
|
|
||||
local *PK; |
|
||||
open PK,'>','eckey-priv.der'; binmode(PK); |
|
||||
print PK $private_der; |
|
||||
close |
|
||||
open PK,'>','eckey-pub.pem'; |
|
||||
print PK $public_pem; |
|
||||
close PK; |
|
||||
|
|
||||
open PK,'>','eckey.yml'; |
|
||||
print PK "--- # eckey\n"; |
|
||||
printf PK "pk: %s\n",Dump($pk->key2hash); |
|
||||
printf PK "...\n"; |
|
||||
close PK; |
|
||||
|
|
||||
|
|
||||
exit $?; |
|
||||
|
|
||||
1; # $Source: /my/perl/script/eckeygen.pl $ |
|
@ -1 +1 @@ |
|||||
Subproject commit d4bea95cde2025454813231b121ffffa846eee0a |
|
||||
|
Subproject commit d1fd3ef3a87ec1bd14c33ef19e106c86fde4e78f |
@ -1 +1 @@ |
|||||
salt: 8163726777753892901 |
|
||||
|
salt: 8163726777754382880 |
@ -0,0 +1,14 @@ |
|||||
|
|
||||
|
|
||||
|
set -e |
||||
|
for f in tx*.yml; do |
||||
|
echo f: $f |
||||
|
#cat $f | sed -e "s/$/%0a/g" | curl -s -X POST http://127.0.0.1:8089/api/0.0/istxvalid -d @- |
||||
|
cat $f | json_xs -f yaml | grep -v 'null' | curl -s -X POST http://127.0.0.1:8089/api/0.0/settx -d @- |
||||
|
echo '' |
||||
|
done |
||||
|
for f in tx*.json; do |
||||
|
cat $f | curl -s -X POST http://127.0.0.1:8089/api/0.0/settx -d @- |
||||
|
echo '' |
||||
|
done |
||||
|
|
@ -0,0 +1,17 @@ |
|||||
|
--- # toychain's runtime state |
||||
|
|
||||
|
# cashash mode |
||||
|
trackmode: 1 |
||||
|
# verification node |
||||
|
skip_balance_check: 1 |
||||
|
|
||||
|
# special blocks: |
||||
|
genhash: ~ |
||||
|
nullhash: ~ |
||||
|
|
||||
|
# transactions: |
||||
|
txgen: ~ |
||||
|
txcoin: ~ |
||||
|
|
||||
|
# misc. |
||||
|
ipfsgw: 8390 |
@ -0,0 +1 @@ |
|||||
|
salt: 3029492618445148610 |
@ -0,0 +1,20 @@ |
|||||
|
--- |
||||
|
inputs: |
||||
|
- |
||||
|
Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: 11 |
||||
|
outputs: |
||||
|
- |
||||
|
ZF2egd6zrw6EcLJt5TmKPzjMSMpyVmkRCKKehLaaakZEU: 7 |
||||
|
- |
||||
|
ZCCWdhnf5aQ3oFMt6JxULAjmCNkB8DNaLpB3Fzcc6V3PN: 1 |
||||
|
- |
||||
|
Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: 3 |
||||
|
payload: This is an example of transaction |
||||
|
signatures: |
||||
|
- |
||||
|
Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: |
||||
|
- Zan1RjNCSDtQtvuBVNvwvNKwWDwN9tPRGFbmmRoJQFeophTFHq6cAsvskowPgHpKWR1LUc5usEwqRLyxcGLzYYc91k8VENiT4H |
||||
|
- |
||||
|
ZCCWdhnf5aQ3oFMt6JxULAjmCNkB8DNaLpB3Fzcc6V3PN: |
||||
|
- Z381YwxTinKz9QgQQzbRSfi4C9B9GTHJhv6TPiq5qeffrLneeST9QtNeueMXsUVzXmA1jTycJAti5D5YdZRojx7kTDRVv1WoD |
||||
|
timestamp: '1623683269225552702' |
@ -0,0 +1 @@ |
|||||
|
{"signatures":[{"michelc":["ZHjX1cinn46FbTioY43qo2ZmfgnjZzXKRMiVN3tZRbxkzg61hNdKRoGptqeFa2tT5kzHqrSUTNcHFTfsLYSz5eDRGXmL3wzc1Gt","2021-06-14 19.54.28","[michelc,0,a]"]},{"anonymous":["ZHjX1cin92axvE1YtoPZyakN1HSFZmXpFxqSVqaWz1S3eyVA5rxTohXUcjcR5sPG9apfTEy34dSUyMPPuN2ngQNDMEFrEgZqbMN","2021-06-14 19.54.28","[anonymous,0,a]"]}],"inputs":[{"ZX3hz85Vayc3Nhfs43ADhTeJXkDJ3fnXtfRiDW4pQzYRQ":"6"}],"nonce":"3976914969180171529","pow":"3976914969180292365","timestamp":"1623693268225555737","outputs":[{"Z24zaLMH6SCfAoC8ndS9XunjrkVpZW5tprhrZdSq3CcXWQ":"3"},{"Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq":"2"}],"message":"This is an other example for transaction"} |
@ -0,0 +1,23 @@ |
|||||
|
--- |
||||
|
message: This is an other example for transaction |
||||
|
inputs: |
||||
|
- ZX3hz85Vayc3Nhfs43ADhTeJXkDJ3fnXtfRiDW4pQzYRQ: 3 |
||||
|
nonce: '3976914969180171529' |
||||
|
outputs: |
||||
|
- |
||||
|
Z24zaLMH6SCfAoC8ndS9XunjrkVpZW5tprhrZdSq3CcXWQ: 3 |
||||
|
- |
||||
|
Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: 2 |
||||
|
pow: '3976914969180292365' |
||||
|
signatures: |
||||
|
- |
||||
|
michelc: |
||||
|
- ZHjX1cinn46FbTioY43qo2ZmfgnjZzXKRMiVN3tZRbxkzg61hNdKRoGptqeFa2tT5kzHqrSUTNcHFTfsLYSz5eDRGXmL3wzc1Gt |
||||
|
- 2021-06-14 19.54.28 |
||||
|
- "[michelc,0,a]" |
||||
|
- |
||||
|
anonymous: |
||||
|
- ZHjX1cin92axvE1YtoPZyakN1HSFZmXpFxqSVqaWz1S3eyVA5rxTohXUcjcR5sPG9apfTEy34dSUyMPPuN2ngQNDMEFrEgZqbMN |
||||
|
- 2021-06-14 19.54.28 |
||||
|
- "[anonymous,0,a]" |
||||
|
timestamp: '1623693268225555737' |
@ -0,0 +1,35 @@ |
|||||
|
{ |
||||
|
"inputs" : [ |
||||
|
{ |
||||
|
"ZX3hz85Vayc3Nhfs43ADhTeJXkDJ3fnXtfRiDW4pQzYRQ" : "5" |
||||
|
} |
||||
|
], |
||||
|
"message" : "This is an other example for transaction", |
||||
|
"nonce" : "3976914969180171529", |
||||
|
"outputs" : [ |
||||
|
{ |
||||
|
"Z24zaLMH6SCfAoC8ndS9XunjrkVpZW5tprhrZdSq3CcXWQ" : "3" |
||||
|
}, |
||||
|
{ |
||||
|
"Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq" : "2" |
||||
|
} |
||||
|
], |
||||
|
"pow" : "3976914969180292365", |
||||
|
"signatures" : [ |
||||
|
{ |
||||
|
"michelc" : [ |
||||
|
"ZHjX1cinn46FbTioY43qo2ZmfgnjZzXKRMiVN3tZRbxkzg61hNdKRoGptqeFa2tT5kzHqrSUTNcHFTfsLYSz5eDRGXmL3wzc1Gt", |
||||
|
"2021-06-14 19.54.28", |
||||
|
"[michelc,0,a]" |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"anonymous" : [ |
||||
|
"ZHjX1cin92axvE1YtoPZyakN1HSFZmXpFxqSVqaWz1S3eyVA5rxTohXUcjcR5sPG9apfTEy34dSUyMPPuN2ngQNDMEFrEgZqbMN", |
||||
|
"2021-06-14 19.54.28", |
||||
|
"[anonymous,0,a]" |
||||
|
] |
||||
|
} |
||||
|
], |
||||
|
"timestamp" : "1623693268225555737" |
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
--- |
||||
|
message: approved 100 coins transaction for blocks mined by Florence M. Buzick for Luke S. Didyk |
||||
|
timestamp: '1626168575783464960' |
||||
|
inputs: |
||||
|
- coinbase: 100 |
||||
|
nonce: '7717044746294770303' |
||||
|
outputs: |
||||
|
- Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: 100 |
||||
|
- miner: 0 |
||||
|
pow: '7717044746294792842' |
||||
|
signatures: |
||||
|
- coinbase: |
||||
|
- Zan1RjQUyrJ3JizN1nERKLNWukKB11QMuFEEV6LrdQtYLPncesNz26jdgp1WfM5Ky2DTgJZHwVpFkem39Z846F2rjKwwcMRC4h |
||||
|
- Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: |
||||
|
- Z381YwxUem1mcUiuBAuXevAJ8zaWhHRL9uCsx1Qix21gbSSpszfnwF1qVCxsPCHj7HPeLetVpKJaok3UH3gQ72AEXfTbmqcEW |
||||
|
- miner: |
||||
|
- ZHjX1cinqAEpNp7wUuX6P2jXWzZFRGQvuCtG78bVRv6w3hrXU2xihQKBDnniee4yA5sRzbxUZgqnzvzQfJsUQCzUf7T9xUDisF6 |
@ -1,11 +1,16 @@ |
|||||
--- |
--- |
||||
message: This is a coinbase transaction of 100 coins to be distributed to Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq |
|
||||
inputs: |
inputs: |
||||
- coinbase: 100 |
|
||||
outputs: |
|
||||
- Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: 100 |
|
||||
timestamp: '1625385951347499858' |
|
||||
|
- |
||||
|
coinbase: 100 |
||||
|
message: This is a coinbase transaction of 100 coins to be distributed to Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq |
||||
nonce: '3976914969180171529' |
nonce: '3976914969180171529' |
||||
|
outputs: |
||||
|
- |
||||
|
Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: 100 |
||||
pow: '3976914969180292365' |
pow: '3976914969180292365' |
||||
signatures: |
signatures: |
||||
- coinbase: ~ |
|
||||
|
- |
||||
|
coinbase: |
||||
|
- Z381YwyamFBjdvLNZCUcfoTqNQpxBzCznG9yaYsdFSztN4z9ZEyGDvpjnY33nq91WdjYk6zMuuUDdtvw5nxo6MYKVHcxPYGMJ |
||||
|
- 2021-07-07 22.49.00 |
||||
|
timestamp: '1625385951347499858' |
@ -1,9 +1,9 @@ |
|||||
--- |
|
||||
message: This is an exemple of transaction with 3 coins going to Trina M. and 2 coins to Michel C. |
|
||||
|
--- # Example of Transaction of the ToyChain |
||||
|
message: This is an example of transaction with 3 coins going to Trina M. and 2 coins to Michel C. |
||||
timestamp: '1623693268225555737' |
timestamp: '1623693268225555737' |
||||
nonce: '3976914969180171529' |
nonce: '3976914969180171529' |
||||
inputs: |
inputs: |
||||
- ZX3hz85Vayc3Nhfs43ADhTeJXkDJ3fnXtfRiDW4pQzYRQ: 3 |
|
||||
|
- ZX3hz85Vayc3Nhfs43ADhTeJXkDJ3fnXtfRiDW4pQzYRQ: 6 |
||||
outputs: |
outputs: |
||||
- Z24zaLMH6SCfAoC8ndS9XunjrkVpZW5tprhrZdSq3CcXWQ: 3 |
- Z24zaLMH6SCfAoC8ndS9XunjrkVpZW5tprhrZdSq3CcXWQ: 3 |
||||
- Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: 2 |
- Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: 2 |
@ -0,0 +1,2 @@ |
|||||
|
--- |
||||
|
... |
@ -0,0 +1,19 @@ |
|||||
|
--- |
||||
|
inputs: |
||||
|
- ZX3hz85Vayc3Nhfs43ADhTeJXkDJ3fnXtfRiDW4pQzYRQ: 8 |
||||
|
message: This is an exemple of transaction with 3 coins going to Trina M. and 2 coins to Michel C. |
||||
|
nonce: '3976914969180171529' |
||||
|
outputs: |
||||
|
- Z24zaLMH6SCfAoC8ndS9XunjrkVpZW5tprhrZdSq3CcXWQ: 3 |
||||
|
- Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: 2 |
||||
|
pow: '3976914969180879919' |
||||
|
signatures: |
||||
|
- michelc: |
||||
|
- ZHjX1cinn46FbTioY43qo2ZmfgnjZzXKRMiVN3tZRbxkzg61hNdKRoGptqeFa2tT5kzHqrSUTNcHFTfsLYSz5eDRGXmL3wzc1Gt |
||||
|
- 2021-06-14 19.54.28 |
||||
|
- "[michelc,0,a]" |
||||
|
- anonymous: |
||||
|
- ZHjX1cin92axvE1YtoPZyakN1HSFZmXpFxqSVqaWz1S3eyVA5rxTohXUcjcR5sPG9apfTEy34dSUyMPPuN2ngQNDMEFrEgZqbMN |
||||
|
- 2021-06-14 19.54.28 |
||||
|
- "[anonymous,0,a]" |
||||
|
timestamp: '1623693268225555737' |
@ -0,0 +1 @@ |
|||||
|
{"txaddr":"ZCBtx7Wg59hvMogWDchKVcGUMo68qDe2dkRfzaskAh3G","outputs":[{"Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq":"100"},{"miner":"0"}],"message":"agreed to give 100 for coinbase transaction to Z21G...stq","nonce":"7717044746241858558","inputs":[{"coinbase":"100"}],"timestamp":"1625714463012468224","signatures":[{"coinbase":["ZHjX1cinHZFWDANGjhJtVn9QMcj4Ra1ejfcZCoccEpLBstEKXD2cvV3b1pP2kC4uhr4BS5g7sARoXarh2C9MyD2e2hpCCvgNYMx"]},{"Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq":["Zan1RjVTEjuzF4fi8FPrWxnsnba6p8co5Kcwob6DWoxFU17cuSNQMogKqfhE5WNFgPu1aD77kLcYkBaHoBh4QNq8NPtpMVkHCx"]},{"miner":["Z381YwxKfWGTkTz8iC7NFxD3wCXwRNWBPeyoGxBVTprpbKP8fC48e4b31i9mcjcrsdVJvon91rUtXZBDv9C1KcvthF5oX4v86"]}],"pow":"7717044746294553205"} |
@ -0,0 +1,18 @@ |
|||||
|
--- |
||||
|
txaddr: ZCBtx7Wg59hvMogWDchKVcGUMo68qDe2dkRfzaskAh3G |
||||
|
message: agreed to give 100 for coinbase transaction to Z21G...stq |
||||
|
timestamp: '1625714463012468224' |
||||
|
inputs: |
||||
|
- coinbase: 100 |
||||
|
outputs: |
||||
|
- Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: 100 |
||||
|
- miner: 0 |
||||
|
nonce: '7717044746241858558' |
||||
|
pow: '7717044746294553205' |
||||
|
signatures: |
||||
|
- coinbase: |
||||
|
- ZHjX1cinHZFWDANGjhJtVn9QMcj4Ra1ejfcZCoccEpLBstEKXD2cvV3b1pP2kC4uhr4BS5g7sARoXarh2C9MyD2e2hpCCvgNYMx |
||||
|
- Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: |
||||
|
- Zan1RjVTEjuzF4fi8FPrWxnsnba6p8co5Kcwob6DWoxFU17cuSNQMogKqfhE5WNFgPu1aD77kLcYkBaHoBh4QNq8NPtpMVkHCx |
||||
|
- miner: |
||||
|
- Z381YwxKfWGTkTz8iC7NFxD3wCXwRNWBPeyoGxBVTprpbKP8fC48e4b31i9mcjcrsdVJvon91rUtXZBDv9C1KcvthF5oX4v86 |
@ -1,11 +0,0 @@ |
|||||
--- |
|
||||
timestamp: '1623683269225552702' |
|
||||
inputs: |
|
||||
- coinbase: 50 |
|
||||
nonce: '3976914969180171529' |
|
||||
outputs: |
|
||||
- Z21GdiEggiGa7TPNaqGY8coBy97LoRNpPVu9fxig75nstq: 50 |
|
||||
message: This is a coinbase transaction of 50 coins for the genesis block |
|
||||
pow: '3976914969180292365' |
|
||||
signatures: |
|
||||
- coinbase: Zan1RjVTw7GPVyd7aygjWSrGCtX3M8CVRu3NAyqLC8MToNPE93ju4RrFFjunnbeTYnudR2gSKCamK82xjEfWEtGzGvTRDw25MG |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue