Skip to content

Instantly share code, notes, and snippets.

@resilience-me
Last active October 20, 2015 00:01
Show Gist options
  • Save resilience-me/e822bc240a3861d61acb to your computer and use it in GitHub Desktop.
Save resilience-me/e822bc240a3861d61acb to your computer and use it in GitHub Desktop.
/** Bitcoin Smart-Contract with Resilience protocol
* pre-blockchain version for enthusiasts
*/
var express = require('express');
var app = express();
var bodyParser = require('body-parser')
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
var bitcore = require('bitcore')
var http = require('request-promise-json')
/** The contract manages its own bitcoin address
*
*/
var privateKey = new bitcore.PrivateKey();
var address = privateKey.toAddress();
/** Now create keys to communicate with the smart-contract
*
*/
var smartContractKey = null
/** Let the issuer of the contract set the contracts smartContractKey - make sure it's a very big number (think quindecillion)
*
*/
app.post('/register_smartContractKey/', function (req, res){
if(smartContractKey === null){
smartContractKey = req.body.smartContractKey
res.send("your own secret key is now: "+ smartContractKey + "make sure you use a very big number (think quindecillion). it's your responsibility to use a secure key. Update your smartContractKey with: POST "+host+"/"+smartContractKey+"/update_smartContractKey/" +' JSON: {"smartContractKey": new_smartContractKey}' )
}
})
/** Let the issuer of the contract change the contracts smartContractKey
*
*/
app.post('/'+smartContractKey+'/update_smartContractKey/', function (req, res){
smartContractKey = req.body.smartContractKey
res.send("your own secret key is now: "+ smartContractKey)
})
var legal_certificate = String // eg. https://e-estonia.com/citizen_id/registered_services/resilience
// should return the bitcoin address associated with this smart-contract
/** Let other smart-contracts verify the legal identity of this smart-contract
*
*/
app.get('/'+address+'/identify/', function(req, res){
res.send(legal_certificate)
})
/** Let the issuer of the contract update the contracts legal certificate
*
*/
app.post('/'+smartContractKey+'/update_legal_certificate/', function (req, res) {
legal_certificate = req.body.url
res.send(legal_certificate)
});
var host = String
/** Let the issuer of the contract register the contracts host
*
*/
app.post('/register_host/', function (req, res){
host = req.headers.host
res.send("host registered: "+host)
})
var trusted_identity_providers = null
/** Let the issuer of the contract get identity providers that the contract trusts
*
*/
app.get('/'+smartContractKey+'/trusted_identity_providers/', function (req, res){
res.send(trusted_identity_providers)
})
/** Let the issuer of the contract set identity providers that the contract trusts
*
*/
app.post('/'+smartContractKey+'/update_trusted_identity_providers/', function (req, res){
// example: truested_identiy_providers = ["http://openID.ee", "http://identi.fi"]
// an identity control returns the bitcoin address associated with the identiy. hard to fake.
// example: GET http://openID.ee/johan.nygren/services/resilience
// returns bitcoin address
trusted_identity_providers = req.body.trusted_identity_providers
res.send(trusted_identity_providers)
})
var trusted_hosts = null
/** Let the issuer of the contract get hosts that the contract trusts. A trusted host could for example allow the contracs code to be audited. Or, the host could set up the contract and wouch for its validity.
*
*/
app.get('/'+smartContractKey+'/trusted_hosts/', function (req, res){
res.send(trusted_hosts)
})
/** Let the issuer of the contract set hosts that the contract trusts
*
*/
app.post('/'+smartContractKey+'/update_trusted_hosts/', function (req, res){
trusted_hosts = req.body.trusted_hosts
res.send(trusted_hosts)
})
var dividendRate = Number
/** Let the issuer of the contract edit the contracts dividendRate
*
*/
app.post('/'+smartContractKey+'/edit_dividend_rate/', function (req, res) {
dividendRate = req.body.dividendRate
res.send(dividendRate)
});
/** Let the issuer of the contract fetch the contracts address
*
*/
app.post('/'+smartContractKey+'/address/', function (req, res){
res.send(address)
})
var unrecieved_dividends = null // todo: this needs to be verified by some trust-infrastructure
/** Let other smart contracts update the contracts unrecieved dividends - needs to be verified by some third party, horizon blockchain for example
*
*/
app.post('/'+address+'/unrecieved_dividends/', function (req, res){
unrecieved_dividends += req.body.unrecieved_dividends //todo: fix this
})
var dividend_pathways = []
/** Subscribe to notifications for the contracts bitcoin address
*
*/
var WebSocket = require('ws');
var conn = new WebSocket("wss://ws.chain.com/v2/notifications");
conn.onopen = function (ev) {
var req = {type: "address", address:address, block_chain: "testnet3"};
conn.send(JSON.stringify(req));
};
conn.onmessage = function (ev) {
var x = JSON.parse(ev.data);
/**
* To ensure that your connection stays alive during periods of inactivity (for example, when there is a long time between new blocks)
* the Chain API will occasionally send a Websocket Notification Result of type heartbeat.
* Your application can simply ignore this data.
*/
if(x.payload.type !== "heartbeat") {
console.log(x);
var Fraction = require('fractional').Fraction
}
// add swarm-redistribution algorithm here
// https://github.com/p2p-safety-net-co-op-dividend-scheme/server/blob/master/connect_transaction.js
};
/** Let the issuer of the contract use the contracts funds
*
*/
app.post('/'+smartContractKey+'/send_payment/', function (req, res) {
http.get("https://tbtc.blockr.io/api/v1/address/unspent/"+address)
.then(function (resultJson) {
var utxo = []
for(var i = 0; i<resultJson.data.unspent.length; i++){
if(resultJson.data.unspent[i].confirmations>0){
utxo.push({
"txId" : resultJson.data.unspent[i].tx,
"outputIndex" : resultJson.data.unspent[i].n,
"address" : resultJson.data.address,
"script" : resultJson.data.unspent[i].script,
"satoshis" : Number(resultJson.data.unspent[i].amount)*100000000
})
}
}
return utxo
})
.then(function (utxo){
console.log(utxo[0])
var utxo = utxo
var transaction = new bitcore.Transaction()
transaction.from(utxo)
.to(req.body.destination, req.body.amount)
.change(address)
.addData(host)
.sign(privateKey);
var tx = transaction.toString()
return tx
})
.then(function (tx){
http.post('http://tbtc.blockr.io/api/v1/tx/push', {hex:tx}).then(function (resultJson){
console.log(resultJson)
}).catch(function(error){console.log(error)})
})
})
/** Let other smart-contracts fetch the dividend pathways of this contract
*
*/
app.get('/'+address+'/dividend_pathways/', function(req, res){
res.send(dividend_pathways)
})
/** Let other smart-contracts fetch the dividend rate of this contract
*
*/
app.get('/'+address+'/dividendRate/', function(req, res){
res.send(dividendRate)
})
app.listen(process.env.PORT || 8080);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment