Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

evo-token

Make a token on Dash Platform and hand it out.

Publishing a token, minting it, sending it and airdropping it to a list of .dash names. One binary with a window and a command line: run it with no arguments and it opens a window, run it with a subcommand and it prints. It holds no wallet and keeps no database, reads a key when it needs one and forgets it when the job ends.

Why it exists

Dash Evo Tool does all of this and more. What it does not do is hand a token out to a list: there is no airdrop anywhere in it, and its command line and MCP server carry no token operation at all — they cover identities, wallets, masternodes, network and shielded, and stop there. So a token cannot be handed out from a script, a cron job or a pipeline today.

It is not a fork. The token logic in Dash Evo Tool is a thin layer over dash-sdk's own transition builders, so what was worth taking from it was the map — which builder does what, which key each transition needs, how a contract carrying a token is assembled — rather than the code. That map, and Platform's own configuration presets, are what this is built on.

Build

cargo build --release

Needs a protoc with its bundled includes, because two build scripts generate protobuf code. Installing only the binary gives you google/protobuf/timestamp.proto: File not found, which reads like a missing file in this project and is not:

curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v25.2/protoc-25.2-linux-x86_64.zip
sudo unzip -o protoc-25.2-linux-x86_64.zip -d /usr/local bin/protoc 'include/*'

The window

evo-token

Three screens: look a token up, make one, hand it out. The look-up box takes a contract ID, a .dash name or an identity ID and works out which it got; a name or identity shows everything that identity holds, with a button per row that carries the contract into the hand-out form. The network sits top right and says so in red when it is mainnet. Everything a button does is reported line by line in the log at the bottom, including the failures.

The key is typed into the screen that needs it and lives only as long as the job. Nothing is saved between runs, which is the difference from Dash Evo Tool: it keeps an encrypted wallet because you leave it open, and this does not because you do not.

The one thing the window does worse than the command line is a long airdrop. Its record of what landed is in memory, so if it stops halfway you have the successful lines in the log and nothing on disk. The command line writes a ledger, so it can be re-run.

The command line

Everything defaults to testnet. Add --network mainnet to spend real money.

evo-token info <contract-id>
evo-token balance alice.dash                          # everything they hold
evo-token balance alice.dash --contract <contract-id> # one token

evo-token create --name Waffle --supply 1000 --identity alice.dash
evo-token mint  --contract <id> --amount 100 --to bob.dash --identity alice.dash
evo-token send  --contract <id> --amount 10  --to bob.dash --identity alice.dash
evo-token airdrop --contract <id> --list recipients.txt --identity alice.dash

The key

Never a flag: a flag lands in your shell history, in ps, and in any log that records a command line. Either

export EVO_TOKEN_WIF=...
evo-token send ...

or --key-file key.wif, or --key-file - to read it from a pipe.

It wants the WIF of an AUTHENTICATION key. Which security level is the chain's call and it differs per action: publishing a contract takes CRITICAL or HIGH, moving a token takes CRITICAL. So an identity can be able to make a token and unable to move it. When the chain refuses on level, the refusal is printed with that identity's own authentication keys next to it, so the answer is in the error.

Airdrops

A list is recipient amount per line, # starts a comment:

alice.dash                                     100
bob.dash                                       50
FKZZFDTfGdSWUmL2g7H9e46pMJMPQp9DHQcvjrsS6884   25   # by id, also fine

Every handout is its own state transition, so a list of 200 is 200 chances to be interrupted. Two things follow from that. Everything is resolved and added up first, so a typo on line 180 costs nothing on line 1. And each handout that lands is appended to recipients.txt.done; re-running the same command skips what is already there and carries on. On the first failure it stops rather than grinding through 190 more lines of the same fault.

--dry-run reads the list, resolves every name and checks the total against your balance without sending anything or asking for a key.

--mint makes new tokens for each recipient instead of moving ones you hold. That needs a token that still allows minting, and it grows the supply.

Where the token list comes from

Everything else here reads the chain. The list of tokens an identity holds cannot: balances live in a tree keyed by identity and nothing walks it, so every SDK call wants the token IDs you are trying to discover. That list comes from pshenmic's public indexer, the same data platform-explorer.com shows.

It is trusted to name things and never to count them. The balances are read from the chain in one call, so a stale answer can hide a token or list an empty one and can never invent a balance. The issuer's .dash name comes from DPNS rather than from the indexer's own aliases, because on mainnet those two disagree. When the indexer is unreachable, everything driven by a contract ID still works and only discovery is lost.

What a token costs

Read off the protocol's own fee schedule and shown before you press the button, because none of it can be undone afterwards:

the contract 0.1 DASH
the token on it 0.1 DASH
each keyword 0.1 DASH
a perpetual distribution 0.1 DASH
a pre-programmed schedule 0.1 DASH

A description is free. So a plain token is 0.2 DASH and two keywords double it. Measured on testnet: a token with no keywords cost 20,063,143,440 credits and one with two keywords 40,167,891,320, which is the table plus a fraction of a thousandth for processing and storage. Both numbers are pinned in a test.

create also says what is legal, costs money and is probably not meant — a ceiling equal to the starting supply on a mintable token, say, which leaves nothing to mint.

What create decides for you

Almost nothing about a token can be changed after it is published, and the contract cannot be withdrawn. The defaults here:

--powers mint-burn (the default) lets the issuer mint more and burn its own. fixed means the supply is what it starts as, forever. full adds freezing a holder's balance and pausing the token. Destroying a frozen balance is never switched on.

History is on and not configurable. What a token's holders are can only be worked out by replaying its transfers, so a token without history is one nobody can audit.

The perpetual distribution rule is opened on purpose. Platform's presets set it to NoOne for every level below full, so a plain mint-and-burn token can never be given a distribution schedule afterwards — and evotools.dev/tokens publishes tokens with exactly that door nailed shut. Since handing tokens out is what this tool is for, create leaves it changeable by the contract owner. --lock-distribution nails it shut deliberately, and that is permanent.

Note the asymmetry: a perpetual distribution can be added later, because TokenConfigurationChangeItem allows it. A pre-programmed one cannot — it is not in that list at all, so it can only ever be set at publication.

What is proven and what is not

Reading is exercised against live testnet from the command line: info and balance return the same numbers as the evotools token fixture, including a token ID derived independently of it. The airdrop's guards are exercised too — a recipient that is the sender, a total above the balance, a recipient listed twice.

The window opens and its buttons call exactly the same functions, but it has not been clicked through.

create has been broadcast for real, from the window, on testnet: contract BMyKLvwm1bHu17SPLj3cdLQZaSyz1ztm5NowJ7jpVWbi, a fixed-supply token of 1,000 Waffles. That first run also found a bug worth keeping in mind. The publish landed and the window then reported "No contract with that ID on this network", because it fetched the contract back from the network to read the token off it, and the next query hit a node that had not applied the block yet. The answer from the broadcast already is the contract, so it is read from there now and the ID is printed before anything else can fail.

send has been broadcast too, from the window: 10 nekoT to alice.dash on testnet, transition E76089111E47FFD59ADB9721C0B6048EB095273771CE28C167DC5099A16D007C. It also failed on screen while succeeding on chain, with

Proof verification error: ... unknown contract with id ... in token verification

The trusted context provider fetches quorum keys by itself but serves data contracts only from what it has been handed, and nothing had handed it this one. Verifying the proof that comes back from a token transition needs the contract that defines the token, and its configuration keyed by token ID. Both are given to the provider now, before anything is signed.

That was the second failure in a row that was really a success, so failures of this shape now say so: a proof is checked after the write, so an error about one says nothing about whether the transition landed. The airdrop says it too, and names the recipient to check, because its ledger only records what came back as done — a handout that landed behind a failed check would otherwise be sent twice by a re-run.

create was then run twice more from the window, which is where the fee table above came from, and where a third failure turned out to be honest: Protocol error: Insufficient identity ... balance 35438100760 required 40000100000. Nothing was published that time. The tool now reads the identity's credits and refuses before signing, saying the shortfall in DASH rather than in credits.

mint and airdrop still have not been broadcast.

Credit

Built on dash-sdk and its trusted context provider, pinned to one revision of dashpay/platform. The window is egui, the same toolkit Dash Evo Tool uses.

Dash Evo Tool (MIT, Dash Core Group) is where the shape of the token operations was learned. No code was copied from it.

MIT.

About

Make a token on Dash Platform and hand it out — one binary that opens a desktop window or runs as a CLI. Airdrop to a list of .dash names. Part of evotools.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages