Skip to content
/ swap Public

The idea behind this project is to give people an option to exchange products and services without money (barter).

Notifications You must be signed in to change notification settings

Gelassen/swap

Repository files navigation

Swap

The idea behind this project is to give people an option to exchange products and services without money (barter).

Case study: Open Exchange platform
Swap tech notes, part 1: smart contracts integration
Swap tech notes, part 2: test coverage
Swap tech notes, part 3: server and mobile clients
Swap tech notes, part 4: automatization
Docker: multicomponent project deployment

Github Actions CI

Similar to the case of government-rus tests passes locally, but on the server one test has been failing which marks CI run as unsuccessful. The root cause of this is unclear. Build reports created at the end of the build work as 2nd source of confidence as a workaround of this issue.

Tech doc in user stories

As a user I open an app and write services I can offer.

As a user I open an app and write services or products I am interested in.

As a user after finish profile with "I can offer" & "I am interested in" I can find people who offers services I am interested in.

As an application I can chain people (more than two) who are interested in services offered by at least one in chain.

Installation

This is a client-server application with use of ethereum chain. The cost of deployment and operation of project work on Mainnet force us to use private own network. At time of writing development goes with help of Goerly testnet.

  1. sudo apt install mysql-server [for more details: https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-ubuntu-20-04]
  2. Server would require database which creation and configuration file lays in the repository:
$ mysql -u <username> -p
$ CREATE DATABASE <db_swap, test_db_swap or prod_db_swap>
$ exit;
$ mysql -u -p db_swap < db_swap_schema.sql
  1. Server is run by setting production configuration file and running commands: $npm install && npm run start:prod
  2. Android mobile client would require release build with sing keys generated by you.
  3. Ethereum chain contracts, SwapValue.sol and SwapChain.sol would require deployment. Their addresses available after depoloyment should be passed to mobile client and server configs.
  4. Mobile client operates with chain over java\kotlin wrappers which require binary code of the compiled contracts. Binary code is available after execution $npx hardhat compile

Deploy own self-hosted chain

  1. Create folders for nodes
  2. Create accounts in nodes:

$geth --datadir ./node1/data account new

pwd: node1

Public address of the key: 0x06Ba36FeA25dAAc20d7d00f95a491566E80a610a Path of the secret key file: node1/data/keystore/UTC--2022-11-07T07-00-25.976610112Z--06ba36fea25daac20d7d00f95a491566e80a610a

$geth --datadir ./node2/data account new

pwd: node2

Public address of the key: 0xaB781fEF949CB48a554C15Be2c36b9E1d2663dee Path of the secret key file: node2/data/keystore/UTC--2022-11-07T07-02-51.751446401Z--ab781fef949cb48a554c15be2c36b9e1d2663dee

$geth --datadir ./node3/data account new

pwd: node3

Public address of the key: 0xDb4E3996071D1B0d37336b6D082ee0176395749b Path of the secret key file: node3/data/keystore/UTC--2022-11-07T07-03-44.502277991Z--db4e3996071d1b0d37336b6d082ee0176395749b

  1. Generate genesis block:

$puppeth

  1. Export chain configuration:

$puppeth (reselect option 2. Manage existing genesis)

  1. Initialize all nodes with chain config:
$geth --datadir ./node1/data init <chain config>.json
$geth --datadir ./node2/data init <chain config>.json
$geth --datadir ./node3/data init <chain config>.json
  1. Start nodes:

A.

$geth --datadir ./node1/data --port 2001 (default authrpc.port 8551)
$geth --datadir ./node2/data --port 2002 --authrpc.port 8552
$geth --datadir ./node3/data --port 2003 --authrpc.port 8553

B. (preferable)

$./swap/blockchain/start_nodes.sh
$<enter your root pwd>

The script is tested on Ubuntu 22.04, but still should be POSIX-compatible.

The script is partly finished. There is a not complete issue with passing ```enode`` url to each node. More details regarding this issue are here: https://unix.stackexchange.com/questions/724525/custom-scenario-for-linux-shell-script/726158#726158

This script will start nodes available over http and print enode url for each node. You still have to add them manually as peers which is described in the next step.

  1. Link all nodes with a main one:
$geth attach ipc:node1/data/geth.ipc
$admin.nodeInfo.enode
(reply would be something similar to "enode://64dccd02d5d1166cfb4913f0d0c164dff2b9c61fd55182461010569e15319c7ff5cb4dc8b502e441c38c80ae1b42c2cc95c7e170ed973bb0353d766669c5447c@195.178.22.21:2001?discport=39805")
$geth attach ipc:node2/data/geth.ipc
$admin.addPeer("enode://64dccd02d5d1166cfb4913f0d0c164dff2b9c61fd55182461010569e15319c7ff5cb4dc8b502e441c38c80ae1b42c2cc95c7e170ed973bb0353d766669c5447c@127.0.0.1:2001")

Repeat for all nodes: each node should have reference in peers on all OTHERS nodes. Known issue: https://github.com/ethereum/go-ethereum/issues

  1. Set reward collector:
$miner.setEtherbase(<account for collecting rewards from mining>)
  1. To solve invalid address error which appears on contract's method invocation:
web3.eth.defaultAccount = web3.eth.coinbase
  1. Unlock account to make it available to either collect the reward from mining or withdraw ether on transaction execution:
personal.unlockAccount("0x62f8dc8a5c80db6e8fcc042f0cc54a298f8f2ffd")

Please note, unlock account is not avaiable by default for nodes run with http access due security breach reasons. For development purpouses nodes are run over http with flag --allow-insecure-unlock, for deployment in the production alternative way should be found.

  1. To make node miner:
$geth attach ipc:node3/data/geth.ipc
$miner.start()
$miner.stop()
$eth.getBalance(eth.accounts[0])
  1. Deploy nodes:
npx hardhat run --network localhost scripts/deploy.ts

Some extra commands:

$admin.peers
$txpool.status
$var contract = eth.contract(abi)
$contract.at('<contract address>').methodCall()

$ var tx = { from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(0.1, 'ether') };
$ eth.sendTransaction(tx);

$ web3.eth.getGasPrice(function(e, r) { console.log(r) })

Important points

Each change on solidity contract changes its bytecode. Client side uses Java\Kotlin wrapper of the contract with its bytecode under the hood. It means changes in solidity code should lead to change in Java\Kotlin code simultaneously.

Web3j offers automation of this process over its console tool. However its work is not stable. I had issues to run it, eventually I successfully managed to get SwapValue ERC721 token, but not a SwapChain. Therefore manual change of the binary code in Java\Kotlin contracts wrappers is the most reliable way to get this done.

Inspired by

The idea to use barter with assist of the modern tech was heard by me from russian ex-oligarch Herman Sterligov during finance crisis in 2008. The idea of matching and chaining people together by their needs and offers has borrowed few things from dead Google project Schemer (https://gcemetery.co/google-schemer/)

Contacts

For reporting issue use 'Issues' tab, for offers -- pull requests.

Email: [email protected]

About

The idea behind this project is to give people an option to exchange products and services without money (barter).

Resources

Stars

Watchers

Forks

Packages

No packages published