Last active
October 20, 2015 00:01
-
-
Save resilience-me/e822bc240a3861d61acb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** 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