@laborx/solidity-user-lib
v0.9.0
Published
User contracts
Downloads
27
Readme
User smart contracts library
Part of LaborX project. Provides a set of smart contracts to organize an environment with users and 2FA access
- UserRegistry - keeps track of created users in a system;
- UserBackendProvider - contract that provides services in a centralized way;
- UserFactory - creates users (UserRouter contract) with defined parameters and registers them in UserRegistry;
- Recovery - base contract for centralized user recovery;
- UserBackend - user shared library contract that is used to move all the logic into separate contract;
- UserRouter - user facade contract; all the time a user interacts exactly with UserRouter contract; see UserInterface contract;
- UserProxy - representative of a user in the system; all tokens and possessions will be held by user proxy contract;
- UserInterface - interface of a user contract; use
UserInterface.at(userRouter.address)
to perform calls.
Multisig
Multisignature contracts support different strategies for owners to submit and confirm transactions according to their roles.
Two-factor authentication
Role system is created to support two-factor authentication (2FA), where two roles are introduced:
- original owner (ROLE_ORIGINAL_OWNER);
- oracle (ROLE_ORACLE).
Original owner is the contract owner of UserRouter smart contract and he is allowed to initiate all multisignature operations. His participanting is required for all operations since 2FA requires 2 owners to confirm transaction, but only ROLE_ORIGINAL_OWNER is allowed to submit them.
Oracle role is a thirdparty account that only confirms submitted transactions and cannot initiate any submit operation.
Thirdparty accounts
The next logical continuation of 2FA is supporting thirdparty accounts that are governed by server-side and could have a lot of agility to buy/sell/manage user's account in automatic/semi-automatic way. These accounts have their own associated role ROLE_THIRDPARTY_OWNER and have attributes from both ROLE_ORIGINAL_OWNER and ROLE_ORACLE:
- thirdparty accounts could initiate transactions (and invoke submit operations);
- thirdparty accounts are mutualy exclusive with ROLE_ORIGINAL_OWNER which means that they cannot both submit and confirm target transaction.
All operations should be submitted and confirmed only by the next rules:
|submit\confirm|ROLE_ORIGINAL_OWNER|ROLE_ORACLE|ROLE_THIRDPARTY_OWNER| |---|:----:|:----:|:-----:| |ROLE_ORIGINAL_OWNER|-|yes|no| |ROLE_ORACLE|no|-|no| |ROLE_THIRDPARTY_OWNER|no|yes|-|
For example, transaction couldn't be initiated by ROLE_ORIGINAL_OWNER and then be confirmed by ROLE_ORIGINAL_OWNER himself - it is impossible because of multisig nature, or transaction couldn't be submitted by ROLE_THIRDPARTY_OWNER and confirmed by ROLE_ORIGINAL_OWNER.
Cashback
Issue that arises before multisig implementation where any server-side confirmation needed that all these operations should be paid somehow by someone either by sending ether like in oraclize services or having an already full pocket of cryptocurrency on this server account.
Cashback feature allowes to pay for confirmation immediately in the moment of confirmation (or operation submission in case of thirdparty accounts). Concept of this is placed in EIP-86 but still in discussion progress, so we need an implementation on our own until this functionality will be put in production.
Cashback provides a way to refund all gas expences for submit/confirm transactions made by server-side accounts: ethers will be withdrawn/sent back from user's proxy account to server-side account. There is a drawback here - no instruments nor possibilities to calculate a gas spent on a transaction (we actually can do that but on only predictable input data: no bytes, no array types, no strings). But it was found an estimation of transaction's gas spendings according to experiments and calculations: coefficient that depicts (nonzero bytes count)/(full input data bytes count) and allows us to calculate the only unknown variable in transaction cost calculations.
This approach takes a bit more than actual transaction takes but much much less if we would've started calculating input data non-zero bytes by ourselves: we see that as a good compromise to solve that non-trivial problem.
Cashback could be turned on/off and could be changed by setting up input data coefficient to updated your data specifics. According to made experiments the optimal value for variable-data length data is 0.35 (or 35% of non-zero bytes). This value might and should be corrected during lifetime.
Installation
Organized as npm package this smart contracts could be easily added to a project by
npm install -s solidity-user-lib
There is also packages to support solc-0.4.21 version because of problems with deployment (old ethereum clients, new compiler features, etc.). This packages are not published but available as a separate branches in repository. They duplicate main versioning and have the next name template:
backport/package-v[package version]-solc-v0.4.21
.
Usage
Right before you decided to use them add this library to package dependencies and import any contract according to this pattern, for example:
import "solidity-shared-lib/contracts/UserFactory.sol";
or
import "solidity-shared-lib/contracts/UserBackendProvider.sol";
Cause you might want to use UserFactory or other contracts without any changes (if you want to then skip this paragraph), you will need to deploy this contract. But due to imperfection of truffle framework when you write in migration files const UserFactory = artifacts.require("UserFactory")
this artifact will not be found. You have two options:
- Inherit from UserFactory and truffle will automatically grap contract's artifact;
- Create a solidity file, for example, Imports.sol and add an
import
statement of UserFactory and all other contracts that you need. (I would recommend this one because it will not produce one more contract name and looks more reasonable.)
Details
Prerequisites
Before any steps of deploying and using user contract first you need to prepare Storage, StorageManager, Roles2Library contracts (or get them if they were previously set up).
Migrations
Migration templates are presented in ./migrations_templates
folder so you can use them as a scaffolding for your own configuration. Basic scenarios covered by migration templates are:
- deploying UserBackend contract;
- deploying UserRegistry contract;
- deploying UserBackendProvider contract and setup backend and registry contracts;
- deploying Recovery contract;
- deploying and initializing UserFactory contract; setup access rights for making records into UserRegistry
Full and the most recent setup steps could be found in ./test-ts/user/deploy.ts
file.
For more information and use cases look at tests.
Development
Setup
Starting from v0.3.0 library support typescript, contract autogeneration and typed environment.
Before any development:
npm install
npm run compile && npm run compile:force && npm run compile:test
Last commands compile project's contracts, build contract interfaces and compile typescript tests.
Development cycle
- Develop smart contracts
npm run compile
- to compile contracts and update artifacts in ./build/contracts- add/write tests; use typescript and provided helpers to cover new functionality with tests
npm run compile:test
- will compile typescript tests and put them in test directorynpm run test
or any othernpx truffle test test/
command to run tests
Commits that are merged to develop
branch from feature/[feature name]
branch should follow commitish guidelines and this one.
Release
To release a new version:
- Create
git checkout -b release/release-v[new package version]
branch fromdevelop
npx standard-version --dry-run
to check if all goes okaynpx standard-version
bump up version and make real changes (update CHANGELOG.md, update package version). No git tag will be added during this step. Seepackage.json/standard-version/skip/
path to update this behavior.- Create MR to
master
branch and wait for all tests to pass - Update merge commit message to
Release v[package-version]
- Setup tag on
master
branchgit tag v[package-version]
- Merge release branch in
develop
branchgit merge --no-ff release/release-v[new package version]
with--no-ff
option. - Now release branch could be removed from all sources.