Here we make a custom Coin contract, test it, and make a package for others to use. We will do this with truffle, so you will need truffle and spore installed. Install both with:
$ npm -g i truffle eth-spore
Development on ethereum is usually done on a separate chain. Here we recommend using testrpc, which is build on top of pyethereum. Install and run it with:
$ pip install eth-testrpc
$ testrpc
On your first run, spore will guide you trough a setup process. The package naming resolution is done on the ethereum chain, therefore a connection to a rpc node is required. If you don't provide an own rpc node, spore will access the chain trough a central rpc server spore.memhub.io:8545
, but the use of an own rpc node is highly recomended. The package content and its header is stored on ipfs. Here Spore also provides a default fallback to the standard gateway on gateway.ipfs.io:80
. For the full experience, please install ipfs and use it locally.
We will further assume that you have connected spore with an own rpc node and local ipfs.
The ethereum foundation and others have already written coin contracts. Also there is a standard API for coin contracts, so that the coin can be openly traded on a decentralized exchange and easily accessed with a wallet. To see what other people have already done, we can search Spore for Coin
:
Because Spore is a decentral package manager there is no server, where you can send your search query to. Therefore you'll have to download all package headers to your local machine and perform a local search. Depending on the amount of packages and your ipfs/rpc connection this may take a while.
Lets update its database:
$ spore update
Packages updated: spore, owned, mortal, coin, spore_instance, a
Great. Now you have all package headers in your local database. Lets search for coins:
$ spore search coin
last update was a few seconds ago
Found 1 results for search coin:
coin: Coin proposal by ethereums standardized contract api
Awesome, there is already a coin package out there which we will use as a basis for own implementation.
Lets look on the info of this package:
$ spore info coin
{
"name": "coin",
"version": "0.1.0",
"description": "Coin proposal by ethereums standardized contract api",
"dependencies": {},
"contracts": {
"currency": "QmeziEPS49PKRtchFEy4QRHYG25PYoTaqtHRA5NbsLrecq"
},
"tags": [],
"root": "QmZaaK9DhBVTtGRDbTtPih5RsYmRZwd7vw6jHCWuXmcBHS",
"solc": "0.1.3-4457170b",
"pv": "0.0.8"
}
Now we clone this package to change it.
$ spore clone coin
coin cloned!
This will create a coin
directory containing all package files. In this tutorial
we will use truffle as our dev-framework, so we need to make a truffle project out of coin:
$ cd coin
$ truffle init:config
Truffle uses the information in config/app.json
on which contract to deploy, so we need to put our coin contract in here:
...
"deploy": [
"currency"
],
...
Now we want to extend the coin contract in such a way, that we keep the power to destroy it. For this, there is also already a package which allows the creator of an contract to destroy it.
$ spore info mortal
{
"name": "mortal",
"version": "0.1.0",
"description": "alow suicide by owner.",
"dependencies": {
"owned": "QmdAtZ66QjSJ6AuyX6Vp3s7SVZXwrj7txf6GS3C9gBaoyd"
},
"contracts": {
"mortal": "QmVca2MpQJTwpK4YZzi4Rea5txezQxALcdKsdcmCj42JLf"
},
"tags": [],
"root": "QmVPB4M51FMWRN11xioYQe22hDjJ1ExyTUQBpcCD6tZK1d",
"solc": "0.1.3-4457170b",
"pv": "0.0.8"
}
Take a notice here, that a contract which is mortal has also be owned by somebody, therefore the package mortal depends on the package owned.
First we have to install this package:
$ spore install mortal
Package mortal installed.
After this, we have to import and assign mortal to our contract contracts/currency.sol
. The end result has to look like this:
$ head -5 contracts/currency.sol
import "mortal";
contract currency is mortal {
struct Account {
uint balance;
Take a notice here, that although we imported our mortal contract, its location
is still somewhere in the spore_packages
directory. To point the compiler
to the right file, we can simply use the link command which resolves all
missing imports with the correct ones:
$ spore link
Changed import in contracts/currency.sol to ../spore_packages/mortal-Y9v8ruHW/contracts/mortal
This will leave contracts/coin.sol
with:
$ head -5 contracts/currency.sol
import "../spore_packages/mortal-Y9v8ruHW/contracts/mortal";
contract currency is mortal {
struct Account {
uint balance;
Now we are ready to go and write some tests on our mortal coin contract:
test/mortalcoin.js
$ cat test/mortalcoin.js
contract('currency', function(accounts) {
it('has to be mortal', function(done) {
// setup default account
web3.eth.defaultAccount = web3.eth.coinbase;
// get the instance
var currencyInstance = currency.at( currency.deployed_address );
// has to be a contract
assert( web3.eth.getCode( currency.deployed_address ) > 2 );
// kill the contract
currencyInstance.kill().then( function( tx ){
// has to be dead
assert.equal( web3.eth.getCode( currency.deployed_address ), '0x' );
done();
});
});
});
test it:
$ truffle test
Using environment test.
Compiling contracts...
Contract: currency
✓ has to be mortal (441ms)
1 passing (627ms)
and deploy it:
$ truffle deploy -e production
This will deploy mortalcoin to your production environment. That was fast, right?
If you want to allow others the usage of mortalcoin along with your test
you can publish it as a package:
Change the name of the project from coin to mortalcoin in your spore.json
file.
Add the tests file with:
$ spore add test/
Added Files:
test/mortalcoin.js
And publish your package:
$ spore publish
Congratulation! You have successfully created an own currency and enable others to easily replicate your work.