vault-tree 0.1.0 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -3
- data/CHANGE_LOG.md +15 -0
- data/Gemfile.lock +15 -5
- data/README.md +12 -15
- data/Rakefile +19 -4
- data/features/.nav +11 -0
- data/features/contracts/asymmetric_vault.feature +23 -0
- data/features/contracts/block_chain_key_transfer.feature +34 -0
- data/features/contracts/one_two_three.feature +22 -0
- data/features/contracts/readme.md +111 -0
- data/features/contracts_and_vaults.md +134 -0
- data/features/contributing_to_vault_tree.md +42 -0
- data/features/decision_tree.md +16 -0
- data/features/enforcement_problem.md +20 -0
- data/features/exceptions.feature +56 -5
- data/features/install_and_usage.md +57 -0
- data/features/keywords/assembled_shamir_key.feature +57 -0
- data/features/keywords/contents.feature +24 -0
- data/features/keywords/decryption_key.feature +10 -0
- data/features/keywords/dh_key.feature +56 -0
- data/features/keywords/external_data.feature +11 -0
- data/features/keywords/generated_shamir_key.feature +55 -0
- data/features/keywords/key.feature +38 -0
- data/features/keywords/master_passphrase.feature +68 -0
- data/features/keywords/public_encryption_key.feature +14 -0
- data/features/keywords/random_number.feature +44 -0
- data/features/keywords/readme.md +3 -0
- data/features/keywords/split_key.feature +54 -0
- data/features/keywords/unlocked.feature +51 -0
- data/features/manipulating_contracts.md +84 -0
- data/features/readme.md +6 -0
- data/features/steps/asymmetric_vault.steps.rb +41 -0
- data/features/steps/block_chain_key_transfer.steps.rb +43 -0
- data/features/steps/core.steps.rb +57 -104
- data/features/steps/exceptions.steps.rb +45 -1
- data/features/steps/one_two_three.steps.rb +57 -0
- data/features/steps/secret_sharing.steps.rb +36 -0
- data/features/support/contract_fixtures/asymmetric_vault.0.1.0.json +69 -0
- data/{spec/support/fixtures → features/support/contract_fixtures}/blank_simple_test_contract.json +0 -0
- data/features/support/contract_fixtures/block_chain_key_transfer.0.1.0.json +59 -0
- data/{spec/support/fixtures → features/support/contract_fixtures}/broken_contract.json +0 -0
- data/features/support/contract_fixtures/one_two_three.0.7.0.json +108 -0
- data/{spec/support/fixtures → features/support/contract_fixtures}/simple_test_contract.json +0 -0
- data/features/support/contract_fixtures/template.json +33 -0
- data/features/what_is_vault_tree.md +18 -0
- data/lib/vault-tree.rb +23 -6
- data/lib/vault-tree/contract/close_validator.rb +0 -7
- data/lib/vault-tree/contract/contract.rb +13 -2
- data/lib/vault-tree/contract/doorman.rb +22 -21
- data/lib/vault-tree/contract/vault.rb +18 -2
- data/lib/vault-tree/exceptions/exception_template.erb +0 -0
- data/lib/vault-tree/exceptions/failed_unlock_attempt.rb +6 -0
- data/lib/vault-tree/exceptions/vault_tree_exception.rb +18 -0
- data/lib/vault-tree/keywords/assembled_shamir_key.rb +44 -0
- data/lib/vault-tree/keywords/{vault_contents.rb → contents.rb} +0 -0
- data/lib/vault-tree/keywords/decryption_key.rb +1 -6
- data/lib/vault-tree/keywords/{shared_key.rb → dh_key.rb} +2 -2
- data/lib/vault-tree/keywords/external_data.rb +19 -0
- data/lib/vault-tree/keywords/generated_shamir_key.rb +57 -0
- data/lib/vault-tree/keywords/key.rb +13 -0
- data/lib/vault-tree/keywords/keyword_interpreter.rb +6 -6
- data/lib/vault-tree/keywords/public_encryption_key.rb +1 -5
- data/lib/vault-tree/keywords/random_number.rb +1 -1
- data/lib/vault-tree/keywords/split_key.rb +19 -0
- data/lib/vault-tree/keywords/unlocked.rb +1 -1
- data/lib/vault-tree/lock_smith.rb +182 -0
- data/lib/vault-tree/lock_smith/assembled_shamir_key.rb +64 -0
- data/lib/vault-tree/lock_smith/dh_key_pair.rb +10 -0
- data/lib/vault-tree/lock_smith/generated_shamir_key.rb +65 -0
- data/lib/vault-tree/lock_smith/split_key.rb +23 -0
- data/lib/vault-tree/{config/path_helpers.rb → path_helpers.rb} +26 -2
- data/lib/vault-tree/util/json.rb +1 -0
- data/lib/vault-tree/{config → util}/string.rb +1 -5
- data/lib/vault-tree/version.rb +1 -1
- data/spec/assembled_shamir_key_spec.rb +79 -0
- data/spec/generated_shamir_key_spec.rb +52 -0
- data/spec/lock_smith_spec.rb +90 -0
- data/spec/secret_sharing_spec.rb +43 -0
- data/support/scripts/libsodium_ubuntu.sh +1 -1
- data/vault-tree.gemspec +3 -2
- metadata +123 -41
- data/features/core.feature +0 -44
- data/lib/vault-tree/config/dependencies.rb +0 -4
- data/lib/vault-tree/config/lib.rb +0 -2
- data/lib/vault-tree/lock_smith/asymmetric_cipher.rb +0 -31
- data/lib/vault-tree/lock_smith/crypto_hash.rb +0 -11
- data/lib/vault-tree/lock_smith/digital_signature.rb +0 -32
- data/lib/vault-tree/lock_smith/encryption_key_pair.rb +0 -25
- data/lib/vault-tree/lock_smith/random_number.rb +0 -11
- data/lib/vault-tree/lock_smith/shared_key_pair.rb +0 -12
- data/lib/vault-tree/lock_smith/signing_key_pair.rb +0 -25
- data/lib/vault-tree/lock_smith/symmetric_cipher.rb +0 -25
- data/spec/app/locksmith/asymmetric_cipher_spec.rb +0 -25
- data/spec/app/locksmith/signing_key_pair_spec.rb +0 -22
- data/spec/spec_helper.rb +0 -5
- data/spec/support/fixtures/one_two_three-0.5.0.EXP.json +0 -105
- data/spec/support/fixtures/reference_contract.1.0.0.json +0 -227
data/.gitignore
CHANGED
data/CHANGE_LOG.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
## 0.3.3
|
2
|
+
|
3
|
+
* Update to RbNaCl 2.0.
|
4
|
+
* Major changes to crypto lib interface
|
5
|
+
* Now Require Libsodium >= 0.4.3
|
6
|
+
|
7
|
+
## 0.2.3
|
8
|
+
|
9
|
+
* Reorganize features dir to work with Relish
|
10
|
+
* Modify some Cucumber features to explicitly take a hard coded contract
|
11
|
+
|
12
|
+
## 0.2.1
|
13
|
+
|
14
|
+
* First pass implementation of GENERATED_SHAMIR_KEY and ASSEMBLED_SHAMIR_KEY
|
15
|
+
* Using version 0.3 of https://github.com/grempe/secretsharing
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
vault-tree (0.1.
|
5
|
-
rbnacl (=
|
6
|
-
|
4
|
+
vault-tree (0.1.0)
|
5
|
+
rbnacl (= 2.0.0)
|
6
|
+
secretsharing (= 0.3)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: http://rubygems.org/
|
10
10
|
specs:
|
11
|
+
archive-tar-minitar (0.5.2)
|
11
12
|
builder (3.2.2)
|
12
13
|
cucumber (1.3.8)
|
13
14
|
builder (>= 2.1.2)
|
@@ -19,11 +20,18 @@ GEM
|
|
19
20
|
ffi (1.9.3)
|
20
21
|
gherkin (2.12.2)
|
21
22
|
multi_json (~> 1.3)
|
23
|
+
json (1.8.1)
|
24
|
+
mime-types (2.0)
|
22
25
|
multi_json (1.8.1)
|
23
26
|
multi_test (0.0.2)
|
24
|
-
rbnacl (
|
27
|
+
rbnacl (2.0.0)
|
25
28
|
ffi
|
26
|
-
|
29
|
+
relish (0.7)
|
30
|
+
archive-tar-minitar (>= 0.5.2)
|
31
|
+
json (>= 1.4.6)
|
32
|
+
rest-client (>= 1.6.1)
|
33
|
+
rest-client (1.6.7)
|
34
|
+
mime-types (>= 1.16)
|
27
35
|
rspec (2.14.1)
|
28
36
|
rspec-core (~> 2.14.0)
|
29
37
|
rspec-expectations (~> 2.14.0)
|
@@ -32,6 +40,7 @@ GEM
|
|
32
40
|
rspec-expectations (2.14.3)
|
33
41
|
diff-lcs (>= 1.1.3, < 2.0)
|
34
42
|
rspec-mocks (2.14.3)
|
43
|
+
secretsharing (0.3)
|
35
44
|
|
36
45
|
PLATFORMS
|
37
46
|
ruby
|
@@ -39,5 +48,6 @@ PLATFORMS
|
|
39
48
|
DEPENDENCIES
|
40
49
|
bundler (~> 1.3)
|
41
50
|
cucumber
|
51
|
+
relish
|
42
52
|
rspec
|
43
53
|
vault-tree!
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ Vault Tree is a collection of tools for building and executing distributed crypt
|
|
6
6
|
|
7
7
|
Before you begin make sure you checkout the [Vault Tree Homepage] for an overview of the project.
|
8
8
|
|
9
|
-
[Vault Tree Homepage]: http://
|
9
|
+
[Vault Tree Homepage]: http://vault-tree.org
|
10
10
|
|
11
11
|
### Welcome!
|
12
12
|
|
@@ -14,23 +14,19 @@ The Vault Tree Project consists of:
|
|
14
14
|
|
15
15
|
* A JSON based DSL for building Distributed Crytographic Contracts
|
16
16
|
* A a Ruby library to execute these contracts
|
17
|
-
* A
|
17
|
+
* A focal point of collaboration for developers writing and testing interesting crytographic contracts
|
18
18
|
|
19
|
-
[Contracts Repository]: https://github.com/VaultTree/contracts
|
20
19
|
|
21
20
|
### Install
|
22
21
|
|
23
22
|
Before you start:
|
24
23
|
|
25
|
-
* If you just want to use Vault Tree to build and execute contracts go to the [Contracts Repository].
|
26
24
|
* To use the library in your application or want to contribute code, you're in the right place.
|
27
25
|
* Before you pull the trigger on the install remember we have a Vagrant Box.
|
28
26
|
|
29
|
-
[Contracts Repository]: https://github.com/VaultTree/contracts
|
30
|
-
|
31
27
|
Okay, lets begin.
|
32
28
|
|
33
|
-
As a prerequisite get [libsodium] on you machine. This is the underlying cryptographic library that Vault Tree depends on.
|
29
|
+
As a prerequisite get [libsodium] (>= 0.4.3) on you machine. This is the underlying cryptographic library that Vault Tree depends on.
|
34
30
|
|
35
31
|
[libsodium]: https://github.com/jedisct1/libsodium
|
36
32
|
|
@@ -57,7 +53,7 @@ Now that you have libsodium, if you're a Ruby developer you know the drill from
|
|
57
53
|
gem install vault-tree
|
58
54
|
```
|
59
55
|
|
60
|
-
and then
|
56
|
+
and then
|
61
57
|
|
62
58
|
```
|
63
59
|
require 'vault-tree'
|
@@ -89,18 +85,18 @@ Now you just need to Vagrant Up!
|
|
89
85
|
This will download and boot a pre-packaged Linux virtual machine with Vault-Tree and all dependencies already installed.
|
90
86
|
|
91
87
|
Once your VM is downloaded and built. You can go inside with:
|
92
|
-
|
88
|
+
|
93
89
|
```
|
94
|
-
vagrant
|
90
|
+
vagrant ssh
|
95
91
|
```
|
96
92
|
|
97
93
|
As a developer working on Vault Tree you can now go to the VM's directory:
|
98
94
|
|
99
95
|
```
|
100
|
-
/vagrant
|
96
|
+
/vagrant
|
101
97
|
```
|
102
98
|
|
103
|
-
and run `rake`. This will run all the tests and
|
99
|
+
and run `bundle` then `rake`. This will grab your dependincies, run all the tests, and leave you in a good spot to start exploring the code.
|
104
100
|
|
105
101
|
If you're not already familiar, take a few minutes to learn about how Vagrant will [sync your files] to and from the guest machine.
|
106
102
|
|
@@ -108,11 +104,12 @@ If you're not already familiar, take a few minutes to learn about how Vagrant wi
|
|
108
104
|
|
109
105
|
### Is it production ready?
|
110
106
|
|
111
|
-
|
107
|
+
Are you serious? This project has like ... 1 fork and 1 star (Thanks Eric!).
|
108
|
+
We have a long way to go.
|
112
109
|
|
113
|
-
Here are some of the big issues that I
|
110
|
+
Here are some of the big issues that I'm thinking about as we move to version 1.0:
|
114
111
|
|
115
112
|
* This is a crypto application so vulnerabilities need to be identified and corrected. We need more eyes in this area.
|
116
113
|
* We we need to figure out if the supported keywords are sufficient to implement basic secure computation schemes.
|
117
|
-
- For example, Digital Signatures
|
114
|
+
- For example, Digital Signatures are not implemented but could be.
|
118
115
|
- Should they be implemented? What is the use case? Ect. We need to have these conversations.
|
data/Rakefile
CHANGED
@@ -4,14 +4,29 @@ require 'cucumber/rake/task'
|
|
4
4
|
require 'rspec/core/rake_task'
|
5
5
|
require "bundler/gem_tasks"
|
6
6
|
|
7
|
-
task :default
|
7
|
+
task :default do
|
8
|
+
Rake::Task["cuke"].invoke
|
9
|
+
Rake::Task["contracts"].invoke
|
10
|
+
Rake::Task["spec"].invoke
|
11
|
+
end
|
8
12
|
|
9
|
-
Cucumber::Rake::Task.new(
|
13
|
+
Cucumber::Rake::Task.new(:cuke) do |t|
|
10
14
|
# -r means you require all support files first
|
11
15
|
# this allows you to organize and run by subdirectory
|
12
16
|
t.cucumber_opts = "-r features features --format pretty"
|
13
17
|
end
|
14
18
|
|
15
|
-
|
16
|
-
|
19
|
+
Cucumber::Rake::Task.new(:contracts) do |t|
|
20
|
+
# -r means you require all support files first
|
21
|
+
# this allows you to organize and run by subdirectory
|
22
|
+
t.cucumber_opts = "-r features features/contracts --format pretty"
|
23
|
+
end
|
24
|
+
|
25
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
26
|
+
t.rspec_opts = "--format doc"
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'Upload Features and Markdown to Relish'
|
30
|
+
task :relish do
|
31
|
+
puts `relish push vault-tree/vault-tree`
|
17
32
|
end
|
data/features/.nav
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
- what_is_vault_tree.md (What is Vault Tree?)
|
2
|
+
- enforcement_problem.md (Enforcement Problem)
|
3
|
+
- decision_tree.md (Decision Trees)
|
4
|
+
- contracts_and_vaults.md (Contracts and Vaults)
|
5
|
+
- install_and_usage.md (Install and Usage)
|
6
|
+
- manipulating_contracts.md (Manipulating Contracts)
|
7
|
+
- keywords (Keywords):
|
8
|
+
- exceptions.feature (Runtime Exceptions)
|
9
|
+
- contracts (Example Contracts):
|
10
|
+
- contributing_to_vault_tree.md (Contributing to Vault Tree)
|
11
|
+
- native (Native Apps):
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Feature: Asymmetric Vaults
|
2
|
+
|
3
|
+
Goals:
|
4
|
+
* Illustrate the use of an Asymmetric Vault
|
5
|
+
* Understand the DH_KEY reserved word
|
6
|
+
* Illustrate an implementation of Public Key Encryption with Mutual Authentication
|
7
|
+
via the ECDH algorithm
|
8
|
+
|
9
|
+
Ideas:
|
10
|
+
* Notice in the contract that the Locking DH_KEY is formed with
|
11
|
+
a private key, and the public key of the reciprocal party
|
12
|
+
* The cooresponding Unlocking DH_KEY is built and authenticated with a private
|
13
|
+
key and the reciprocal public key
|
14
|
+
|
15
|
+
Scenario: Bob Locks and Alice Unlocks with a Shared Key
|
16
|
+
Given Alice has the blank asymmetric vault contract
|
17
|
+
When she locks all of her public and private keys
|
18
|
+
And she sends the contract to Bob over the internet
|
19
|
+
Then Bob can access of her public keys but not her private keys
|
20
|
+
When Bob locks his public and private keys
|
21
|
+
And He fills and locks the vault containing the message using a DH_KEY
|
22
|
+
And he sends the contract back to Alice over the internet
|
23
|
+
Then Alice can unlock the message with a DH_KEY
|
@@ -0,0 +1,34 @@
|
|
1
|
+
Feature: Block Chain Key Transfer
|
2
|
+
|
3
|
+
This contract introduces the idea of a Bitcoin key transfer.
|
4
|
+
|
5
|
+
Goal:
|
6
|
+
* Two parties wish to transfer the BTC signing key associated with a particular wallet address
|
7
|
+
* To effect this transfer they want to use only a Vault Tree JSON files and the BTC Block Chain
|
8
|
+
* The transfering party wants to maintain control over the precise moment the signing key is
|
9
|
+
released to the receiving party.
|
10
|
+
|
11
|
+
Ideas:
|
12
|
+
* The sending party can use a Block Chain wallet address as the locking key to a symmetric vault.
|
13
|
+
* After generating a hidden wallet address, the sender can use the address to lock the BTC signing
|
14
|
+
key in the vault.
|
15
|
+
* By spending Bitcoins from an origin wallet address (that is know the receiver) to the hidden
|
16
|
+
destination wallet address, the sending party is able to Reveal the encryption key needed to
|
17
|
+
unlock the symmetric vault.
|
18
|
+
|
19
|
+
Notes:
|
20
|
+
* This transfer could prove useful as a step in a more sophisticated contract.
|
21
|
+
* Here we are transfering a BTC Signing Key. This approach could work to transfer any
|
22
|
+
type of private information.
|
23
|
+
* Transfering Signed but Unbroadcasted transactions with this mechanism could open up
|
24
|
+
many new possibilities.
|
25
|
+
|
26
|
+
Scenario: SENDER Transfers a BTC Signing Key to the RECEIVER
|
27
|
+
|
28
|
+
Given the SENDER has the blank contract template
|
29
|
+
And the SENDER chooses an origin address and a concealed destination address
|
30
|
+
And he locks away the secret BTC signing key
|
31
|
+
When the SENDER transfers the contract to the RECEIVER
|
32
|
+
Then the RECEIVER can access the origin wallet address
|
33
|
+
When the SENDER reveals the hidden wallet address by transfering bitcoins from the origin address
|
34
|
+
Then the RECEIVER can unlock the vault to recover the transfered signing key
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Feature: One-Two-Three Contract
|
2
|
+
|
3
|
+
Goal:
|
4
|
+
* Used to demonstrate and test basic Vault Tree functionality
|
5
|
+
* It nicely illustrates how vault keys can be arranged to enforce the terms of a contract
|
6
|
+
* If you are new to the Vault Tree Library it may be helpful to study the details of this contract
|
7
|
+
to gain a better understanding of the core concepts.
|
8
|
+
|
9
|
+
Ideas:
|
10
|
+
* Bob sets up a simple Scavenger Hunt for Alice
|
11
|
+
* He locks a Congratulations Message in the final vault
|
12
|
+
* In order to get to the final message Alice needs to unlock the preceeding vaults with the
|
13
|
+
appropriate keys
|
14
|
+
|
15
|
+
Scenario: Alice and Bob Execute the One Two Three Contract
|
16
|
+
Given Alice has the blank contract
|
17
|
+
When she locks all of her attributes
|
18
|
+
And she sends the contract to Bob
|
19
|
+
Then Bob can access all of her public attributes
|
20
|
+
When Bob locks his attributes
|
21
|
+
And He fills and locks each of the three main vaults
|
22
|
+
Then Alice can execute the contract to recover the final message
|
@@ -0,0 +1,111 @@
|
|
1
|
+
Contracts are a central part of the [Vault Tree Project]. Here is what you
|
2
|
+
need to know:
|
3
|
+
|
4
|
+
* A Vault Tree Contract is simply a [JSON] text file
|
5
|
+
* Every contract is composed of two parts:
|
6
|
+
- The **Header** section, which includes helpful meta data
|
7
|
+
- The **Vaults** section, which can be any collection of _vaults_ that form the
|
8
|
+
contract.
|
9
|
+
* The way in which you, the contract author, organize the vaults will determine the **Self-Enforcing Terms** of your contract.
|
10
|
+
* Each vault will typically contain either an **external data** string that is provided by one of the contract
|
11
|
+
participants, or a key to anther vault.
|
12
|
+
|
13
|
+
### Writing and Simulating Contracts
|
14
|
+
|
15
|
+
If you've made it to this far, then you're ready to build something. You're
|
16
|
+
thinking to yourself:
|
17
|
+
|
18
|
+
* For my Vault Tree Contract to be useful it probably needs to involve more than one person.
|
19
|
+
* I think I can write a contract, but I really need a way to test it out and think through all the different scenarios.
|
20
|
+
* When my final contract is complete it might involve network calls to pass it
|
21
|
+
between parties, queries the Bitcoin Block Chain, or some other crazy step involving the outside world.
|
22
|
+
|
23
|
+
What I really need is a way to **Simulate** how the contract will be used in real life ...
|
24
|
+
|
25
|
+
Enter [Cucumber].
|
26
|
+
|
27
|
+
[Cucumber]: https://github.com/cucumber/cucumber
|
28
|
+
|
29
|
+
Cucumber is a tool designed to test complicated full stack web applications. However, we are going to use it for a slightly different purpose.
|
30
|
+
|
31
|
+
Take a look at this simple example:
|
32
|
+
|
33
|
+
```Gherkin
|
34
|
+
Scenario: Alice and Bob Execute the One Two Three Contract
|
35
|
+
Given Alice has the blank contract
|
36
|
+
When she locks all of her attributes
|
37
|
+
And she sends the contract to Bob
|
38
|
+
Then Bob can access all of her public attributes
|
39
|
+
When Bob locks his attributes
|
40
|
+
And He fills and locks each of the three main vaults
|
41
|
+
Then Alice can execute the contract to recover the final message
|
42
|
+
```
|
43
|
+
|
44
|
+
Great. So we wrote down how the contract is used in some funny looking format ... so what.
|
45
|
+
|
46
|
+
Well, what if we associate each one of these steps in the scenario with some simple Ruby code that interacts with the Vault Tree API. Here are the first three step definitions:
|
47
|
+
|
48
|
+
```Ruby
|
49
|
+
# This file: "features/core/one_two_three/one_two_three.steps.rb"
|
50
|
+
# Associated Contract: "core/one_two_three.0.7.0.json"
|
51
|
+
|
52
|
+
Given(/^Alice has the blank contract$/) do
|
53
|
+
contract_path = VaultTree::ContractsRepo::PathHelpers.core_contracts('one_two_three.0.7.0.json')
|
54
|
+
@contract_json = File.read(contract_path)
|
55
|
+
end
|
56
|
+
|
57
|
+
When(/^she locks all of her attributes$/) do
|
58
|
+
@contract = VaultTree::Contract.new(@contract_json, master_passphrase: 'ALICE_SECURE_PASS', external_data: {})
|
59
|
+
@contract = @contract.close_vault('alice_decryption_key')
|
60
|
+
@contract = @contract.close_vault('alice_public_encryption_key')
|
61
|
+
end
|
62
|
+
|
63
|
+
When(/^she sends the contract to Bob$/) do
|
64
|
+
@contract_json = @contract.as_json
|
65
|
+
@bobs_external_data = {"congratulations_message" => "CONGRATS! YOU OPENED THE THIRD VAULT."}
|
66
|
+
@contract = VaultTree::Contract.new(@contract_json, master_passphrase: 'BOB_SECURE_PASS', external_data: @bobs_external_data)
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
Not only can we easily run the contract throught the library to test that it
|
71
|
+
works, we have a straight forward mechanism for simulating otherwise complicated
|
72
|
+
steps like sending the JSON representation of the contact _over the wire_.
|
73
|
+
|
74
|
+
Some items to keep in mind when you run Cucumber scenarios:
|
75
|
+
|
76
|
+
* Run `rake` instead of `cucumber` when in the VM `/vagrant` dir
|
77
|
+
* This will:
|
78
|
+
- Take care of the wierd cucumber configuration flags needed to handle the unconventional directory structure.
|
79
|
+
- Execute all cucumber scenarios associated with contracts in the `/core` directory
|
80
|
+
|
81
|
+
### Design Opinions
|
82
|
+
|
83
|
+
Vault Tree was written to give contract authors a large amount of flexibilty.
|
84
|
+
There are however some design constraints that were put in place to get the
|
85
|
+
community off to a good start.
|
86
|
+
|
87
|
+
I'll update these in the coming months as we get some more experience writing simple contracts.
|
88
|
+
|
89
|
+
* The Vault Tree interpreter is stateless and always takes a contract as an input
|
90
|
+
* All external data required for contract execution must be provided to the
|
91
|
+
interpreter by the run time that is invoking the API. For example, there are no
|
92
|
+
plans for the interpreter to make any network requests or do file IO.
|
93
|
+
|
94
|
+
|
95
|
+
##### Notes for Developers
|
96
|
+
|
97
|
+
* Let's practice strict [semantic versioning] in managing our contracts.
|
98
|
+
* Edit contracts with the help of an application like [js beatifier].
|
99
|
+
* Ensure proper JSON format with a tool like this [json parser].
|
100
|
+
* Changes to core contracts should produce clean Git diffs.
|
101
|
+
|
102
|
+
[lab]: https://github.com/VaultTree/contracts/tree/master/lab
|
103
|
+
[core]: https://github.com/VaultTree/contracts/tree/master/core
|
104
|
+
[Contracts Repository]: https://github.com/VaultTree/contracts
|
105
|
+
[JSON]: http://www.json.org
|
106
|
+
[Vault Tree Homepage]: http://www.vault-tree.org
|
107
|
+
[Vault Tree Project]: http://www.vault-tree.org
|
108
|
+
[semantic versioning]: http://semver.org
|
109
|
+
[js beatifier]: http://jsbeautifier.org
|
110
|
+
[json parser]: http://json.parser.online.fr
|
111
|
+
[json]: http://json.org
|
@@ -0,0 +1,134 @@
|
|
1
|
+
### Contracts
|
2
|
+
|
3
|
+
Now that we've explored the ideas of a **Contract**, **Contract Enforcement**, and a **Decision Tree**, we can better understand what makes a Vault Tree Contract unique.
|
4
|
+
|
5
|
+
#### Vaults
|
6
|
+
|
7
|
+
Vault Tree Contracts are made by assembling simple structures called **Vaults**.
|
8
|
+
|
9
|
+
A vault is like a digital lock box that stores a single unambiguous piece of information. This piece of information is needed to continue the execution of a contract beyond a certain event.
|
10
|
+
|
11
|
+
The light bulb should turn on when you realize that vaults can hold not only valuable external information, but the **keys to other vaults**.
|
12
|
+
|
13
|
+
#### Contract Properties
|
14
|
+
|
15
|
+
Like regular contracts, Vault Tree Contracts are still modeled as a Decision
|
16
|
+
Tree of events and outcomes. Unlike regular contracts, they have the added
|
17
|
+
benefit of being a **Distributed Cryptographic Contract**. This means:
|
18
|
+
|
19
|
+
* To each event in the contract we add a corresponding vault
|
20
|
+
* A contract becomes a structured collection of vaults
|
21
|
+
* Each Vault encrypts a piece of secret information. This can be external
|
22
|
+
information such as a _URL_ or a _Bitcoin Wallet Address_. More often, a vault will contain the unlocking key to another vault in the contract.
|
23
|
+
* The way in which the contract author **chooses to structure** the releationship between vaults, will determine how the contract is **Enforced**.
|
24
|
+
|
25
|
+
#### Complete Contracts
|
26
|
+
|
27
|
+
Because Vault Tree Contracts should be **self-enforcing** and **programatically executable**, they are by convention [complete contracts].
|
28
|
+
|
29
|
+
In the context of the interpreting library this means the following:
|
30
|
+
|
31
|
+
* Each **Leaf Vault** in the graph should unlock a set of conditions that represents an acceptable contract **Outcome**.
|
32
|
+
* There does not exist any combination of conditions that would ultimately fail to unlock a leaf vault.
|
33
|
+
|
34
|
+
[complete contracts]: http://en.wikipedia.org/wiki/Complete_contract
|
35
|
+
|
36
|
+
#### Contracts as JSON Files
|
37
|
+
|
38
|
+
Just as a common contract is often written on a piece of paper, a Vault Tree contract is typed into a single text file that can be copied and distributed to anyone.
|
39
|
+
|
40
|
+
We chose the [JSON] file format for respresenting contracts. JSON is becoming the mainstream internet serialization format and can be easily read by both humans and computers.
|
41
|
+
|
42
|
+
[JSON]: www.json.org
|
43
|
+
|
44
|
+
|
45
|
+
### Vaults
|
46
|
+
|
47
|
+
We discussed earlier how Vault Tree contracts are just a collection of vaults
|
48
|
+
arranged to enforce the terms of the contract.
|
49
|
+
|
50
|
+
Let's take a look at an example vault:
|
51
|
+
|
52
|
+
```javascript
|
53
|
+
"bob_random_vault_key": {
|
54
|
+
"fill_with": "RANDOM_NUMBER",
|
55
|
+
"lock_with": "KEY['bob_vault_key']",
|
56
|
+
"unlock_with": "KEY['alice_vault_key']",
|
57
|
+
"contents": "rSGrWGL4mEYtpuIaWO/iVGXAA5UUyLeeImSV3SBXzb+C7DW3"
|
58
|
+
}
|
59
|
+
```
|
60
|
+
|
61
|
+
It's important to keep in mind that, **every** vault follows this format. This convention for representing a vault should be sufficient to build any type of simplistic or sophisticated contract.
|
62
|
+
|
63
|
+
#### Vault Id
|
64
|
+
|
65
|
+
The **Vault Id** can be thought of as both the name and the **Unique** identifier of the vault.
|
66
|
+
|
67
|
+
In this case we have:
|
68
|
+
|
69
|
+
```
|
70
|
+
"bob_random_vault_key"
|
71
|
+
```
|
72
|
+
|
73
|
+
Try to give meaningful names that give insight into the locked contents held within the vault. Also, by convention vault names should begin with the name of the vault owner.
|
74
|
+
|
75
|
+
A vault owner is the contract party that is responsibily for filling and locking the vault. In this simple case we have **bob**, but in an employment contract for example, we may have vault owners named **employer** and **employee**.
|
76
|
+
|
77
|
+
It is the responsibility of the contract author to assign vault owners in such a way that there are no contract [moral hazards] or [perverse incentives].
|
78
|
+
|
79
|
+
[moral hazards]: http://en.wikipedia.org/wiki/Moral_hazard
|
80
|
+
[perverse incentives]: http://en.wikipedia.org/wiki/Perverse_incentive
|
81
|
+
|
82
|
+
#### Fill With
|
83
|
+
|
84
|
+
The **fill_with** field identifies the source of the [Plaintext] contents of the
|
85
|
+
vault. It can be:
|
86
|
+
|
87
|
+
* a value generated by the Vault Tree library.
|
88
|
+
* external information that is brought into the contract.
|
89
|
+
* the contents of anther vault.
|
90
|
+
|
91
|
+
In the example above, the Vault Tree interpreter knows to generate a simple random number, and place it into the vault.
|
92
|
+
|
93
|
+
[Plaintext]: http://en.wikipedia.org/wiki/Plaintext
|
94
|
+
|
95
|
+
#### Lock With
|
96
|
+
|
97
|
+
The **lock_with** field identifies the source of the vault's **Locking Key**.
|
98
|
+
|
99
|
+
|
100
|
+
#### Unlock With
|
101
|
+
|
102
|
+
The **unlock_with** field naturally identifies the source of the vault's **Unlocking Key**.
|
103
|
+
|
104
|
+
It may not be obvious, but the reference to the Unlocking key does not necessarily need to be the same as the reference to the **Locking Key**. Here are some examples of where this could be the case:
|
105
|
+
|
106
|
+
* The same key is used to lock and unlock the vault, but copies of this key are
|
107
|
+
* held in two separate vaults. Take a look at the **Block Chain Key Transfer**
|
108
|
+
* contract to see a good example of this.
|
109
|
+
* Vault Tree supports the notion of an **Asymmetric Vault** through the _DSL Keyword_
|
110
|
+
|
111
|
+
```
|
112
|
+
DH_KEY
|
113
|
+
```
|
114
|
+
|
115
|
+
An Asymmetric Vault is locked and unlocked with the help of a [Public-Private](http://en.wikipedia.org/wiki/Public-key_cryptography) keypair. Vault Tree's underlying cryptographic library makes this possible by implementing a cutting edge variant of the [ECDH] key exchange protocol.
|
116
|
+
|
117
|
+
[ECDH]: http://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman
|
118
|
+
|
119
|
+
#### Contents
|
120
|
+
|
121
|
+
As you would expect, this field references the encrypted contents of the vault. In the example above you can see the _Base 64_ encoded ciphertext:
|
122
|
+
|
123
|
+
```
|
124
|
+
"contents": "rSGrWGL4mEYtpuIaWO/iVGXAA5UUyLeeImSV3SBXzb+C7DW3"
|
125
|
+
```
|
126
|
+
Here are some items to keep in mind:
|
127
|
+
|
128
|
+
* Vaults are either **Empty** or **Closed**, this corresponds to either a **Blank Value** or a **Ciphertext Value**
|
129
|
+
* If we want everyone to have access to the contents we simply lock the closed vault with a known public value. For a description on how to do this in practice see the _DSL Keyword_
|
130
|
+
|
131
|
+
```
|
132
|
+
UNLOCKED
|
133
|
+
```
|
134
|
+
|