Skip to content

Commit

Permalink
complete prototype
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmular committed May 13, 2018
1 parent cf5bc70 commit f557c6a
Show file tree
Hide file tree
Showing 18 changed files with 413 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.swp
build/
package_delivery_contract.js
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2018 Ondrej Mular

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
60 changes: 60 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
DOCKER=docker
NETWORK_NAME=eth-testname
DOCKER_RUN_ARGS=--detach --tty --interactive --network $(NETWORK_NAME)
BOOTNODE_IMG=eth-bootnode
NODE_IMG=eth-node
NODES_NUM=3
BUILD_DIR=./build
CONTRACT_SOL=package_delivery.sol

all: run

run: run_bootnode run_nodes

run_bootnode: setup build_bootnode clean_bootnode
$(DOCKER) run $(DOCKER_RUN_ARGS) --name eth-bootnode $(BOOTNODE_IMG)

run_nodes: setup build_node clean_nodes
for i in $$(seq 1 $(NODES_NUM)); do \
$(DOCKER) run $(DOCKER_RUN_ARGS) --name eth-node$$i --env "eth_acc=acc$$i" $(NODE_IMG);\
done

setup: setup_network build_contract

setup_network:
-$(DOCKER) network create --internal $(NETWORK_NAME)

build: build_bootnode build_node build_contract

build_contract: $(CONTRACT_SOL)
mkdir -p $(BUILD_DIR)
docker run -v $$(pwd):/_input:ro -v $$(cd $(BUILD_DIR); pwd):/_output:rw -i ethereum/solc:0.4.23 --combined-json abi,bin --overwrite -o /_output /_input/$(CONTRACT_SOL)
./create_crontract_script.py

build_base: baseimg.docker
$(DOCKER) build -f baseimg.docker -t eth-base .

build_bootnode: build_base bootnode.docker
$(DOCKER) build -f bootnode.docker -t $(BOOTNODE_IMG) .

build_node: build_base node.docker
$(DOCKER) build -f node.docker -t $(NODE_IMG) .

clean: clean_contract clean_containers clean_images clean_network

clean_contract:
-rm -rf package_delivery_contract.js $(BUILD_DIR)

clean_images:
-$(DOCKER) rmi eth-base $(BOOTNODE_IMG) $(NODE_IMG)

clean_network:
-$(DOCKER) network rm $(NETWORK_NAME)

clean_containers: clean_bootnode clean_nodes

clean_bootnode:
-$(DOCKER) rm -f eth-bootnode

clean_nodes:
-$(DOCKER) rm -f $$(for i in $$(seq 1 $(NODES_NUM)); do echo "eth-node$$i"; done)
8 changes: 8 additions & 0 deletions baseimg.docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM fedora:27

ENV geth_pkg geth-alltools-linux-amd64-1.8.6-12683fec
ENV geth_home /root/
ENV bootnode_name eth-bootnode

RUN dnf install -y wget; dnf clean all
RUN wget -nv https://gethstore.blob.core.windows.net/builds/${geth_pkg}.tar.gz && tar -xvzf ${geth_pkg}.tar.gz && rm -f ${geth_pkg}.tar.gz && mv ${geth_pkg} ${geth_home}/geth
1 change: 1 addition & 0 deletions boot.key
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
e9aa0425ad62b9eecd8c0f0861a17f547ba597bb7c7622d24e75ec053d4ec100
7 changes: 7 additions & 0 deletions bootnode.docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM eth-base

# geth/bootnode -genkey boot.key
COPY boot.key ${geth_home}/boot.key
COPY start_bootnode.sh /bin/start_bootnode

CMD ["/bin/start_bootnode"]
1 change: 1 addition & 0 deletions bootnode_id
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
91884f0f60ea2347e16abcc158409271cc011b4d933142dd1ffb2edd920373de9a2cc95ea21944dd4d89b347bb8579b3f6a22cd8ebdad8f9ccd66135b762a567
14 changes: 14 additions & 0 deletions create_crontract_script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env python

import json

contract = json.load(
open("./build/combined.json")
)["contracts"]["/_input/package_delivery.sol:PackageDelivery"]
with open("package_delivery_contract.js", "w+") as f:
f.write("""\
var packageDeliveryAbi = {abi};
var packageDeliveryCode = '0x{code}';
""".format(abi=contract["abi"], code=contract["bin"])
)
35 changes: 35 additions & 0 deletions genesis.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"config": {
"chainId": 12345,
"homesteadBlock": 1,
"eip150Block": 2,
"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"eip155Block": 3,
"eip158Block": 3,
"byzantiumBlock": 4,
"clique": {
"period": 5,
"epoch": 30000
}
},
"nonce": "0x0",
"extraData": "0x0000000000000000000000000000000000000000000000000000000000000000830de593b42d3a007e19553c68f0f4c95e0e6e8f92f4f00f2f5355f5ec1c55512118f1fa537b1864f27292834a6b7129e5ad00e264062c978c48d7050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x47b760000",
"difficulty": "0x1",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",
"alloc": {
"830de593b42d3a007e19553c68f0f4c95e0e6e8f": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
},
"92f4f00f2f5355f5ec1c55512118f1fa537b1864": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
},
"f27292834a6b7129e5ad00e264062c978c48d705": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
}
},
"number": "0x0",
"gasUsed": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
1 change: 1 addition & 0 deletions keystore/830de593b42d3a007e19553c68f0f4c95e0e6e8f
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"address":"830de593b42d3a007e19553c68f0f4c95e0e6e8f","crypto":{"cipher":"aes-128-ctr","ciphertext":"ccccee5012a1c4d60776d2847bb2c99a7b6aa5b89bb27813c13a02b31c85077b","cipherparams":{"iv":"d97fd2beacb3c86a2753bfa7fb87679c"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"5eae42bba2927111d395b2354e9f3e44f589538487e7d2d7bad5d6ff4c02938a"},"mac":"710541e740afb4d61b902296a39c3e58e76a5bfd761b9428b47bc8fb057f191d"},"id":"49a3b284-0715-4f24-9171-a019e16ad015","version":3}
1 change: 1 addition & 0 deletions keystore/92f4f00f2f5355f5ec1c55512118f1fa537b1864
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"address":"92f4f00f2f5355f5ec1c55512118f1fa537b1864","crypto":{"cipher":"aes-128-ctr","ciphertext":"490a953a0775cc7219ce7a2387f1ae228ca99acc9bc2f9d69d6e7948ee628675","cipherparams":{"iv":"958f9bacb98e83f7b5e4291b5c029039"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"eca9045f389ef34c2f25add6f4c3bd1bbeb1bdb2381cabbef11b6be9c6c2d126"},"mac":"69cc13232e6c5830ac5b4135b4207916f48c6bf3e88f55e2b6f0fa57520825e6"},"id":"01adc11d-3151-46a4-9a6e-ee2e008d810b","version":3}
1 change: 1 addition & 0 deletions keystore/f27292834a6b7129e5ad00e264062c978c48d705
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"address":"f27292834a6b7129e5ad00e264062c978c48d705","crypto":{"cipher":"aes-128-ctr","ciphertext":"19e549e155b54db7367ddb8ae85f4299ccbe5b8da5331b069c78fe0cc57ede0e","cipherparams":{"iv":"db8a4b6de73f9d6a52ba4014ebe405b1"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"3697350ba2d855a397e470d131c8ba32dfcc997fb7e2453504970e2f7bfb10d4"},"mac":"adfc8eafdb5941b0aabcb29edf1154d4eefa20a34c6b17afbce90b0e01f2c32f"},"id":"f54fd5c0-7a76-4d63-b7c1-4db7b680d0a4","version":3}
13 changes: 13 additions & 0 deletions node.docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM eth-base

RUN mkdir -p ${geth_home}/chain_data

COPY start_node.sh /bin/start_node
COPY genesis.json ${geth_home}/genesis.json
COPY keystore ${geth_home}/keystore
COPY bootnode_id ${geth_home}/bootnode_id
COPY password ${geth_home}/password
COPY package_delivery_contract.js ${geth_home}/package_delivery_contract.js
COPY package_delivery.js ${geth_home}/package_delivery.js

CMD ["/bin/start_node"]
38 changes: 38 additions & 0 deletions package_delivery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// requires defined packageDeliveryAbi and packageDeliveryCode variables

var acc1 = "0x92f4f00f2f5355f5ec1c55512118f1fa537b1864";
var acc2 = "0xf27292834a6b7129e5ad00e264062c978c48d705";
var acc3 = "0x830de593b42d3a007e19553c68f0f4c95e0e6e8f";

function new_pkg_delivery_contract(carrier_addr, recipient_addr) {
return web3.eth.contract(packageDeliveryAbi).new(
carrier_addr,
recipient_addr,
{
from: web3.eth.accounts[0],
data: packageDeliveryCode,
gas: '4700000'
},
function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log(
'Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash
);
}
}
)
}

function get_existing_pkg_delivery_contract(addr) {
return web3.eth.contract(packageDeliveryAbi).at(addr);
}

function send_tx(arg) {
return arg.sendTransaction({from: eth.accounts[0]})
}

function show_status(obj) {
console.log("Process status: " + obj.get_process_state());
console.log("Package delivery status: " + obj.get_status());
}
158 changes: 158 additions & 0 deletions package_delivery.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
pragma solidity ^0.4.23;

contract Process {
enum State {
Initiated, // 0
InProgress, // 1
Ended // 2
}
State public state;

modifier is_in_progress() {
require(state == State.InProgress, "Process is not in progress");
_;
}

constructor() public {
state = State.Initiated;
}

function start() internal {
require(state == State.Initiated, "Process has been already started");
state = State.InProgress;
}

function end() internal is_in_progress() {
state = State.Ended;
}

function get_process_state() public view returns(State) {
return state;
}
}

contract PackageDelivery is Process {
address public sender;
address public carrier;
address public recipient;
uint failed_deliveries;
uint delivered_confirmation_until;
// set to lower timeout for testing
uint delivered_confirmation_timeout = 60; // in seconds

enum PackageDeliveryState {
Preparing, // 0
HandoverToCarrier, // 1
InDelivery, // 2
HandoverToRecipient, // 3
Delivered, // 4
ReturningToSender, // 5
HandoverToSender, // 6
Returned // 7
}

PackageDeliveryState package_state;

modifier allowed_actor(address _actor) {
require(msg.sender == _actor, "Not authorized");
_;
}

modifier package_in_state(PackageDeliveryState _state) {
require(_state == package_state, "Invalid action");
_;
}

constructor(address _carrier, address _recipient) public {
failed_deliveries = 0;
sender = msg.sender;
carrier = _carrier;
recipient = _recipient;
start();
package_state = PackageDeliveryState.Preparing;
}

function get_status() public view returns (PackageDeliveryState) {
return package_state;
}

function hand_over_to_carrier()
public
is_in_progress()
allowed_actor(sender)
package_in_state(PackageDeliveryState.Preparing)
{
package_state = PackageDeliveryState.HandoverToCarrier;
}

function accept_package_for_delivery()
public
is_in_progress()
allowed_actor(carrier)
package_in_state(PackageDeliveryState.HandoverToCarrier)
{
package_state = PackageDeliveryState.InDelivery;
}

function hand_over_to_recipient()
public
is_in_progress()
allowed_actor(carrier)
package_in_state(PackageDeliveryState.InDelivery)
{
package_state = PackageDeliveryState.HandoverToRecipient;
delivered_confirmation_until = now + delivered_confirmation_timeout;
}

function accept_package()
public
is_in_progress()
allowed_actor(recipient)
package_in_state(PackageDeliveryState.HandoverToRecipient)
{
require(
now <= delivered_confirmation_until,
"Delivery confirmation timed out."
);
package_state = PackageDeliveryState.Delivered;
end();
}

function unable_to_deliver()
public
is_in_progress()
allowed_actor(carrier)
package_in_state(PackageDeliveryState.HandoverToRecipient)
{
require(
now > delivered_confirmation_until,
"Delivery confirmation didn't time out yet."
);
failed_deliveries++;
if (failed_deliveries >= 3) {
package_state = PackageDeliveryState.ReturningToSender;
} else {
package_state = PackageDeliveryState.InDelivery;
}
}

function return_to_sender()
public
is_in_progress()
allowed_actor(carrier)
package_in_state(PackageDeliveryState.ReturningToSender)
{
package_state = PackageDeliveryState.HandoverToSender;
}

function confirm_pkg_return()
public
is_in_progress()
allowed_actor(sender)
package_in_state(PackageDeliveryState.HandoverToSender)
{
package_state = PackageDeliveryState.Returned;
end();
}
}

1 change: 1 addition & 0 deletions password
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1234
12 changes: 12 additions & 0 deletions start_bootnode.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/sh

BOOTNODE_IP=$(getent hosts ${bootnode_name} | awk '{print $1;}')

echo "running: ${geth_home}/geth/bootnode \
-nodekey ${geth_home}/boot.key \
-addr ${BOOTNODE_IP}:30301"
${geth_home}/geth/bootnode \
-nodekey ${geth_home}/boot.key \
-addr ${BOOTNODE_IP}:30301


Loading

0 comments on commit f557c6a

Please sign in to comment.