first commit
This commit is contained in:
commit
50389151bc
|
@ -0,0 +1,6 @@
|
||||||
|
.embark/
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
config/production/password
|
||||||
|
config/livenet/password
|
||||||
|
chains.json
|
|
@ -0,0 +1,11 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Embark</title>
|
||||||
|
<link rel="stylesheet" href="css/app.css">
|
||||||
|
<script src="js/app.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h3>Welcome to Embark!</h3>
|
||||||
|
<p>See the <a href="http://embark.readthedocs.io/en/latest/index.html" target="_blank">Embark's documentation</a> to see what you can do with Embark!</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,6 @@
|
||||||
|
import EmbarkJS from 'Embark/EmbarkJS';
|
||||||
|
|
||||||
|
// import your contracts
|
||||||
|
// e.g if you have a contract named SimpleStorage:
|
||||||
|
//import SimpleStorage from 'Embark/contracts/SimpleStorage';
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
module.exports = {
|
||||||
|
development: {
|
||||||
|
enabled: true,
|
||||||
|
networkType: "custom", // Can be: testnet, rinkeby, livenet or custom, in which case, it will use the specified networkId
|
||||||
|
networkId: "1337", // Network id used when networkType is custom
|
||||||
|
isDev: true, // Uses and ephemeral proof-of-authority network with a pre-funded developer account, mining enabled
|
||||||
|
genesisBlock: "config/development/genesis.json", // Genesis block to initiate on first creation of a development node
|
||||||
|
datadir: ".embark/development/datadir", // Data directory for the databases and keystore
|
||||||
|
mineWhenNeeded: true, // Uses our custom script (if isDev is false) to mine only when needed
|
||||||
|
nodiscover: true, // Disables the peer discovery mechanism (manual peer addition)
|
||||||
|
maxpeers: 0, // Maximum number of network peers (network disabled if set to 0) (default: 25)
|
||||||
|
rpcHost: "localhost", // HTTP-RPC server listening interface (default: "localhost")
|
||||||
|
rpcPort: 8545, // HTTP-RPC server listening port (default: 8545)
|
||||||
|
rpcCorsDomain: "auto", // Comma separated list of domains from which to accept cross origin requests (browser enforced)
|
||||||
|
// When set to "auto", Embark will automatically set the cors to the address of the webserver
|
||||||
|
proxy: true, // Proxy is used to present meaningful information about transactions
|
||||||
|
account: {
|
||||||
|
// "address": "", // When specified, uses that address instead of the default one for the network
|
||||||
|
password: "config/development/password" // Password to unlock the account
|
||||||
|
},
|
||||||
|
targetGasLimit: 8000000, // Target gas limit sets the artificial target gas floor for the blocks to mine
|
||||||
|
wsRPC: true, // Enable the WS-RPC server
|
||||||
|
wsOrigins: "auto", // Origins from which to accept websockets requests
|
||||||
|
// When set to "auto", Embark will automatically set the cors to the address of the webserver
|
||||||
|
wsHost: "localhost", // WS-RPC server listening interface (default: "localhost")
|
||||||
|
wsPort: 8546, // WS-RPC server listening port (default: 8546)
|
||||||
|
simulatorMnemonic: "example exile argue silk regular smile grass bomb merge arm assist farm", // Mnemonic used by the simulator to generate a wallet
|
||||||
|
simulatorBlocktime: 0 // Specify blockTime in seconds for automatic mining. Default is 0 and no auto-mining.
|
||||||
|
},
|
||||||
|
testnet: {
|
||||||
|
enabled: true,
|
||||||
|
networkType: "testnet",
|
||||||
|
syncMode: "light",
|
||||||
|
rpcHost: "localhost",
|
||||||
|
rpcPort: 8545,
|
||||||
|
rpcCorsDomain: "http://localhost:8000",
|
||||||
|
account: {
|
||||||
|
password: "config/testnet/password"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
livenet: {
|
||||||
|
enabled: true,
|
||||||
|
networkType: "livenet",
|
||||||
|
syncMode: "light",
|
||||||
|
rpcHost: "localhost",
|
||||||
|
rpcPort: 8545,
|
||||||
|
rpcCorsDomain: "http://localhost:8000",
|
||||||
|
account: {
|
||||||
|
password: "config/livenet/password"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
privatenet: {
|
||||||
|
enabled: true,
|
||||||
|
networkType: "custom",
|
||||||
|
rpcHost: "localhost",
|
||||||
|
rpcPort: 8545,
|
||||||
|
rpcCorsDomain: "http://localhost:8000",
|
||||||
|
datadir: "yourdatadir",
|
||||||
|
networkId: "123",
|
||||||
|
bootnodes: ""
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,13 @@
|
||||||
|
module.exports = {
|
||||||
|
default: {
|
||||||
|
enabled: true,
|
||||||
|
provider: "whisper", // Communication provider. Currently, Embark only supports whisper
|
||||||
|
available_providers: ["whisper"], // Array of available providers
|
||||||
|
connection: {
|
||||||
|
host: "localhost", // Host of the blockchain node
|
||||||
|
port: 8546, // Port of the blockchain node
|
||||||
|
type: "ws" // Type of connection (ws or rpc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
var utils = require('web3-utils')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
// default applies to all environments
|
||||||
|
default: {
|
||||||
|
// Blockchain node to deploy the contracts
|
||||||
|
deployment: {
|
||||||
|
host: "localhost", // Host of the blockchain node
|
||||||
|
port: 8545, // Port of the blockchain node
|
||||||
|
type: "rpc" // Type of connection (ws or rpc),
|
||||||
|
// Accounts to use instead of the default account to populate your wallet
|
||||||
|
/*,accounts: [
|
||||||
|
{
|
||||||
|
privateKey: "your_private_key",
|
||||||
|
balance: "5 ether" // You can set the balance of the account in the dev environment
|
||||||
|
// Balances are in Wei, but you can specify the unit with its name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
privateKeyFile: "path/to/file" // You can put more than one key, separated by , or ;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mnemonic: "12 word mnemonic",
|
||||||
|
addressIndex: "0", // Optionnal. The index to start getting the address
|
||||||
|
numAddresses: "1", // Optionnal. The number of addresses to get
|
||||||
|
hdpath: "m/44'/60'/0'/0/" // Optionnal. HD derivation path
|
||||||
|
}
|
||||||
|
]*/
|
||||||
|
},
|
||||||
|
// order of connections the dapp should connect to
|
||||||
|
dappConnection: [
|
||||||
|
"$WEB3", // uses pre existing web3 object if available (e.g in Mist)
|
||||||
|
"ws://localhost:8546",
|
||||||
|
"http://localhost:8545"
|
||||||
|
],
|
||||||
|
gas: "auto",
|
||||||
|
contracts: {
|
||||||
|
ballot: {
|
||||||
|
args: [
|
||||||
|
[utils.toHex("proposal 1"), utils.toHex("proposal 2")]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"homesteadBlock": 0,
|
||||||
|
"byzantiumBlock": 0,
|
||||||
|
"daoForkSupport": true
|
||||||
|
},
|
||||||
|
"nonce": "0x0000000000000042",
|
||||||
|
"difficulty": "0x0",
|
||||||
|
"alloc": {
|
||||||
|
"0x3333333333333333333333333333333333333333": {"balance": "15000000000000000000"}
|
||||||
|
},
|
||||||
|
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"coinbase": "0x3333333333333333333333333333333333333333",
|
||||||
|
"timestamp": "0x00",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"extraData": "0x",
|
||||||
|
"gasLimit": "0x7a1200"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
dev_password
|
|
@ -0,0 +1,6 @@
|
||||||
|
module.exports = {
|
||||||
|
default: {
|
||||||
|
available_providers: ["ens"],
|
||||||
|
provider: "ens"
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,35 @@
|
||||||
|
module.exports = {
|
||||||
|
default: {
|
||||||
|
enabled: true,
|
||||||
|
ipfs_bin: "ipfs",
|
||||||
|
provider: "ipfs",
|
||||||
|
available_providers: ["ipfs"],
|
||||||
|
upload: {
|
||||||
|
host: "localhost",
|
||||||
|
port: 5001
|
||||||
|
},
|
||||||
|
dappConnection: [
|
||||||
|
{
|
||||||
|
provider: "ipfs",
|
||||||
|
host: "localhost",
|
||||||
|
port: 5001,
|
||||||
|
getUrl: "http://localhost:8080/ipfs/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
// Configuration to start Swarm in the same terminal as `embark run`
|
||||||
|
/*,account: {
|
||||||
|
address: "YOUR_ACCOUNT_ADDRESS", // Address of account accessing Swarm
|
||||||
|
password: "PATH/TO/PASSWORD/FILE" // File containing the password of the account
|
||||||
|
},
|
||||||
|
swarmPath: "PATH/TO/SWARM/EXECUTABLE" // Path to swarm executable (default: swarm)*/
|
||||||
|
},
|
||||||
|
development: {
|
||||||
|
enabled: true,
|
||||||
|
provider: "ipfs",
|
||||||
|
upload: {
|
||||||
|
host: "localhost",
|
||||||
|
port: 5001,
|
||||||
|
getUrl: "http://localhost:8080/ipfs/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1 @@
|
||||||
|
test_password
|
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = {
|
||||||
|
enabled: true,
|
||||||
|
host: "localhost",
|
||||||
|
port: 8000
|
||||||
|
};
|
|
@ -0,0 +1,155 @@
|
||||||
|
# Voting with delegation.
|
||||||
|
|
||||||
|
# Information about voters
|
||||||
|
voters: public({
|
||||||
|
# weight is accumulated by delegation
|
||||||
|
weight: int128,
|
||||||
|
# if true, that person already voted (which includes voting by delegating)
|
||||||
|
voted: bool,
|
||||||
|
# person delegated to
|
||||||
|
delegate: address,
|
||||||
|
# index of the voted proposal, which is not meaningful unless `voted` is True.
|
||||||
|
vote: int128
|
||||||
|
}[address])
|
||||||
|
|
||||||
|
# This is a type for a list of proposals.
|
||||||
|
proposals: public({
|
||||||
|
# short name (up to 32 bytes)
|
||||||
|
name: bytes32,
|
||||||
|
# int128ber of accumulated votes
|
||||||
|
vote_count: int128
|
||||||
|
}[int128])
|
||||||
|
|
||||||
|
voter_count: public(int128)
|
||||||
|
chairperson: public(address)
|
||||||
|
int128_proposals: public(int128)
|
||||||
|
|
||||||
|
@public
|
||||||
|
@constant
|
||||||
|
def delegated(addr: address) -> bool:
|
||||||
|
# equivalent to
|
||||||
|
# self.voters[addr].delegate != 0x0000000000000000000000000000000000000000
|
||||||
|
return not not self.voters[addr].delegate
|
||||||
|
|
||||||
|
@public
|
||||||
|
@constant
|
||||||
|
def directly_voted(addr: address) -> bool:
|
||||||
|
# not <address> equivalent to
|
||||||
|
# <address> == 0x0000000000000000000000000000000000000000
|
||||||
|
return self.voters[addr].voted and not self.voters[addr].delegate
|
||||||
|
|
||||||
|
# Setup global variables
|
||||||
|
@public
|
||||||
|
def __init__(_proposalNames: bytes32[2]):
|
||||||
|
self.chairperson = msg.sender
|
||||||
|
self.voter_count = 0
|
||||||
|
for i in range(2):
|
||||||
|
self.proposals[i] = {
|
||||||
|
name: _proposalNames[i],
|
||||||
|
vote_count: 0
|
||||||
|
}
|
||||||
|
self.int128_proposals += 1
|
||||||
|
|
||||||
|
# Give a `voter` the right to vote on this ballot.
|
||||||
|
# This may only be called by the `chairperson`.
|
||||||
|
@public
|
||||||
|
def give_right_to_vote(voter: address):
|
||||||
|
# Throws if the sender is not the chairperson.
|
||||||
|
assert msg.sender == self.chairperson
|
||||||
|
# Throws if the voter has already voted.
|
||||||
|
assert not self.voters[voter].voted
|
||||||
|
# Throws if the voter's voting weight isn't 0.
|
||||||
|
assert self.voters[voter].weight == 0
|
||||||
|
self.voters[voter].weight = 1
|
||||||
|
self.voter_count += 1
|
||||||
|
|
||||||
|
# Used by `delegate` below, and can be called by anyone.
|
||||||
|
@public
|
||||||
|
def forward_weight(delegate_with_weight_to_forward: address):
|
||||||
|
assert self.delegated(delegate_with_weight_to_forward)
|
||||||
|
# Throw if there is nothing to do:
|
||||||
|
assert self.voters[delegate_with_weight_to_forward].weight > 0
|
||||||
|
|
||||||
|
target: address = self.voters[delegate_with_weight_to_forward].delegate
|
||||||
|
for i in range(4):
|
||||||
|
if self.delegated(target):
|
||||||
|
target = self.voters[target].delegate
|
||||||
|
# The following effectively detects cycles of length <= 5,
|
||||||
|
# in which the delegation is given back to the delegator.
|
||||||
|
# This could be done for any int128ber of loops,
|
||||||
|
# or even infinitely with a while loop.
|
||||||
|
# However, cycles aren't actually problematic for correctness;
|
||||||
|
# they just result in spoiled votes.
|
||||||
|
# So, in the production version, this should instead be
|
||||||
|
# the responsibility of the contract's client, and this
|
||||||
|
# check should be removed.
|
||||||
|
assert target != delegate_with_weight_to_forward
|
||||||
|
else:
|
||||||
|
# Weight will be moved to someone who directly voted or
|
||||||
|
# hasn't voted.
|
||||||
|
break
|
||||||
|
|
||||||
|
weight_to_forward: int128 = self.voters[delegate_with_weight_to_forward].weight
|
||||||
|
self.voters[delegate_with_weight_to_forward].weight = 0
|
||||||
|
self.voters[target].weight += weight_to_forward
|
||||||
|
|
||||||
|
if self.directly_voted(target):
|
||||||
|
self.proposals[self.voters[target].vote].vote_count += weight_to_forward
|
||||||
|
self.voters[target].weight = 0
|
||||||
|
|
||||||
|
# To reiterate: if target is also a delegate, this function will need
|
||||||
|
# to be called again, similarly to as above.
|
||||||
|
|
||||||
|
# Delegate your vote to the voter `to`.
|
||||||
|
@public
|
||||||
|
def delegate(to: address):
|
||||||
|
# Throws if the sender has already voted
|
||||||
|
assert not self.voters[msg.sender].voted
|
||||||
|
# Throws if the sender tries to delegate their vote to themselves or to
|
||||||
|
# the default address value of 0x0000000000000000000000000000000000000000
|
||||||
|
# (the latter might not be problematic, but I don't want to think about it).
|
||||||
|
assert to != msg.sender and not not to
|
||||||
|
|
||||||
|
self.voters[msg.sender].voted = True
|
||||||
|
self.voters[msg.sender].delegate = to
|
||||||
|
|
||||||
|
# This call will throw if and only if this delegation would cause a loop
|
||||||
|
# of length <= 5 that ends up delegating back to the delegator.
|
||||||
|
self.forward_weight(msg.sender)
|
||||||
|
|
||||||
|
# Give your vote (including votes delegated to you)
|
||||||
|
# to proposal `proposals[proposal].name`.
|
||||||
|
@public
|
||||||
|
def vote(proposal: int128):
|
||||||
|
# can't vote twice
|
||||||
|
assert not self.voters[msg.sender].voted
|
||||||
|
# can only vote on legitimate proposals
|
||||||
|
assert proposal < self.int128_proposals
|
||||||
|
|
||||||
|
self.voters[msg.sender].vote = proposal
|
||||||
|
self.voters[msg.sender].voted = True
|
||||||
|
|
||||||
|
# transfer msg.sender's weight to proposal
|
||||||
|
self.proposals[proposal].vote_count += self.voters[msg.sender].weight
|
||||||
|
self.voters[msg.sender].weight = 0
|
||||||
|
|
||||||
|
# Computes the winning proposal taking all
|
||||||
|
# previous votes into account.
|
||||||
|
@public
|
||||||
|
@constant
|
||||||
|
def winning_proposal() -> int128:
|
||||||
|
winning_vote_count: int128 = 0
|
||||||
|
winning_proposal: int128 = 0
|
||||||
|
for i in range(2):
|
||||||
|
if self.proposals[i].vote_count > winning_vote_count:
|
||||||
|
winning_vote_count = self.proposals[i].vote_count
|
||||||
|
winning_proposal = i
|
||||||
|
return winning_proposal
|
||||||
|
|
||||||
|
# Calls winning_proposal() function to get the index
|
||||||
|
# of the winner contained in the proposals array and then
|
||||||
|
# returns the name of the winner
|
||||||
|
@public
|
||||||
|
@constant
|
||||||
|
def winner_name() -> bytes32:
|
||||||
|
return self.proposals[self.winning_proposal()].name
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"contracts": ["contracts/**"],
|
||||||
|
"app": {
|
||||||
|
"css/app.css": ["app/css/**"],
|
||||||
|
"js/app.js": ["app/js/index.js"],
|
||||||
|
"images/": ["app/images/**"],
|
||||||
|
"index.html": "app/index.html"
|
||||||
|
},
|
||||||
|
"buildDir": "dist/",
|
||||||
|
"config": "config/",
|
||||||
|
"versions": {
|
||||||
|
"web3": "1.0.0-beta",
|
||||||
|
"solc": "0.4.24",
|
||||||
|
"ipfs-api": "17.2.4",
|
||||||
|
"p-iteration": "1.1.7"
|
||||||
|
},
|
||||||
|
"plugins": {}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "embark-vyper-template",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "",
|
||||||
|
"scripts": {
|
||||||
|
"test": "embark test"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"homepage": "",
|
||||||
|
"dependencies": {
|
||||||
|
"embark": "^3.1.5",
|
||||||
|
"web3-utils": "^1.0.0-beta.34"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
// /*global contract, config, it, assert*/
|
||||||
|
/*const SimpleStorage = require('Embark/contracts/SimpleStorage');
|
||||||
|
|
||||||
|
config({
|
||||||
|
contracts: {
|
||||||
|
"SimpleStorage": {
|
||||||
|
args: [100]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
contract("SimpleStorage", function () {
|
||||||
|
this.timeout(0);
|
||||||
|
|
||||||
|
it("should set constructor value", async function () {
|
||||||
|
let result = await SimpleStorage.methods.storedData().call();
|
||||||
|
assert.strictEqual(parseInt(result, 10), 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("set storage value", async function () {
|
||||||
|
await SimpleStorage.methods.set(150).send();
|
||||||
|
let result = await SimpleStorage.methods.get().call();
|
||||||
|
assert.strictEqual(parseInt(result, 10), 150);
|
||||||
|
});
|
||||||
|
});*/
|
Loading…
Reference in New Issue