Browse files

some color games

  • Loading branch information...
1 parent ad2997e commit 236999e2ba0b66a34616f1068150894c41aaef9d @0i0 committed Nov 6, 2012
Showing with 335 additions and 214 deletions.
  1. +88 −0 2.js
  2. +107 −0 async.js
  3. +0 −214 color.js
  4. +64 −0 newcolor.js
  5. +76 −0 scanBlockChain.js
View
88 2.js
@@ -0,0 +1,88 @@
+//order based input merge by output
+
+
+function orderBasedInputMergeByOutput(tx){
+ var orderedTx = {out:[]}
+ , apetite = 0
+ , tasted = 0
+ , eaten = 0
+
+ for (var j = 0, n = tx.out.length; i < n ; ++ i){
+ apetite = tx.out[j].amount
+ eaten = 0;
+ var out =
+ {toAddr : tx.out[j].toAddr
+ ,value : apetite
+ ,prev_inputs : []
+ }
+ while (eaten < apetite && tasted < tx.in.length){
+ eaten += tx.in[tasted].amount;
+ out.prev_inputs.push(tx.in[tasted]);
+ ++tasted;
+ }
+ }
+ return orderedTx;
+}
+
+function getColor(input){
+ color = getByDefenition(prev_tx,sourceAddr);
+ if (color != 'unknown')
+ return color;
+ orderedTx = colorTx(prev_tx);
+ while(orderedTx.out.length>0){
+ out = orderedTx.out.shift();
+ if (out.toAddr == sourceAddr){
+ color = out.color;
+ break;
+ }
+ }
+ return color;
+}
+
+function getColors(inputs){
+ for (var i = inputs.length - 1; i >= 0; i--) {
+ inputs[i].color = getColor(inputs[i]);
+ }
+}
+
+function mixColors(colors){
+ outColor = 'undefined';
+ do{
+ color = colors.shift();
+ if (color != outColor && outColor != 'undefined'){
+ color = 'mixed';
+ break;
+ }
+ outColor = prevInputColor;
+ } while (colors.length > 0);
+ return outColor;
+}
+
+function getTx(txId){
+ xhr = new XMLHttpRequest();
+ xhr.open('GET', 'http://localhost:3333/json/tx/'+txId, true);
+ xhr.onreadystatechange = function(e) {
+ if (xhr.readyState === 4) {
+ if (xhr.status === 200) {
+ debugger;
+ var data = JSON.parse(xhr.responseText);
+ return data;
+ }
+ }
+ };
+ xhr.send(null);
+}
+
+function colorTx(txId){
+ var tx = getTx(txId);
+ var orderedTx = orderBasedInputMergeByOutput(tx);
+ for (var i in orderedTx.out.length){
+ var inputcolors = getColors(orderedTx.out[i].prev_inputs);
+ var color = mixColors(inputcolors);
+ orderedTx.out[i].color = color;
+ }
+ return orderedTx;
+}
+
+var colored = colorTx('d10d7127366229b341a559ddf83b53b9ac6c1b2ca792cb2e81edaf7a595d763b');
+console.log(colored);
View
107 async.js
@@ -0,0 +1,107 @@
+//order based input merge by output
+
+function getByDefenition(prev_tx, sourceAddr){
+ if (
+ prev_tx == "81a39c41ca946d72e8b5de8ba61bbba085252a2b10f075dc1ca8d4118df4981e"
+ && sourceAddr == "1GPwJvMpB4vJPuMwHs9JDAZm9Lh66Y2qnS"
+ )
+ return 'g'
+ else
+ return 'unknown'
+}
+
+function orderBasedInputMergeByOutput(tx,callback){
+ var orderedTx = {out:[]}
+ , apetite = 0
+ , tasted = 0
+ , eaten = 0
+ , err = 'none'
+
+ for (var j = 0, n = tx.out.length; j < n ; ++ j){
+ apetite = parseFloat(tx.out[j].value)
+ eaten = 0;
+ var out =
+ {toAddr : tx.out[j].toAddr
+ ,value : apetite
+ ,prev_inputs : []
+ }
+ while (eaten < apetite && tasted < tx.in.length){
+ eaten += parseFloat(tx.in[tasted].value);
+ out.prev_inputs.push(tx.in[tasted]);
+ ++tasted;
+ }
+ orderedTx.out.push(out)
+ }
+ callback(err, orderedTx);
+}
+
+function getColor(input){
+ if (input.type == 'coinBase')
+ return 'default'
+ color = getByDefenition(input.prev_tx,input.sourceAddr);
+ if (color != 'unknown')
+ console.log('coloring tx: ' + input.prev_tx)
+ orderedTx = colorTx(input.prev_tx);
+ while(orderedTx.out.length>0){
+ debugger;
+ out = orderedTx.out.shift();
+ if (out.toAddr == sourceAddr){
+ color = out.color;
+ break;
+ }
+ }
+ return color;
+}
+
+function getColors(inputs){
+ for (var i = inputs.length - 1; i >= 0; i--) {
+ inputs[i].color = getColor(inputs[i]);
+ }
+}
+
+function mixColors(colors){
+ outColor = 'undefined';
+ do{
+ color = colors.shift();
+ if (color != outColor && outColor != 'undefined'){
+ color = 'mixed';
+ break;
+ }
+ outColor = prevInputColor;
+ } while (colors.length > 0);
+ return outColor;
+}
+
+function getTx(txId,callback){
+ xhr = new XMLHttpRequest();
+ xhr.open('GET', 'http://localhost:3333/json/tx/'+txId, true);
+ xhr.onreadystatechange = function(e) {
+ if (xhr.readyState === 4) {
+ if (xhr.status === 200) {
+ var data = JSON.parse(xhr.responseText);
+ var err = "none"
+ console.log('grabbed: ' + data.hash)
+ return callback(err,data);
+ }
+ }
+ };
+ xhr.send(null);
+}
+
+function colorTx(txId){
+ return getTx(txId,
+ function(err, tx){
+ return orderBasedInputMergeByOutput(tx,function(err,orderedTx){
+ for (var i = 0 , n = orderedTx.out.length; i < n; i++){
+ var inputcolors = getColors(orderedTx.out[i].prev_inputs);
+ var color = mixColors(inputcolors);
+ orderedTx.out[i].color = color;
+ }
+ return orderedTx;
+ })
+ }
+ )
+}
+
+var colored = colorTx('bf2bd6aefa3263988ac27fc1dc5be0e646143363031dc0976f971a73f7a64931');
+console.log(colored);
View
214 color.js
@@ -1,214 +0,0 @@
-//constants
-var COLOR = {
- MIXED: -1,
- UNKNOWN: -2,
- DEFAULT: 0
-};
-
-function uncolored(i) {
- return (i <= 0);
-}
-
-function compute_colors(inputs, outputs) {
- // initialize state
- var cur_amount = 0;
- var cur_color = COLOR.UNKNOWN;
- var i = 0; //input index
-
- for (var o = 0; o < outputs.length; ++o) {
- var want_amount = outputs[o].amount;
-
- if (want_amount > 0) {
- // normal output: make sure we have enough in cur_amount, eating as many inputs as necessary
- while ((cur_amount < want_amount) && (i < inputs.length)) {
-
- if (cur_amount == 0)
- cur_color = inputs[i].color;
- else if (cur_color != inputs[i].color)
- cur_color = COLOR.MIXED;
-
- cur_amount += inputs[i].amount;
- ++i;
- }
-
- if (cur_amount < want_amount)
- return false; // transaction itself is invalid
-
- } else {
- // deal with zero-valued output
- if (cur_amount == 0 && i < inputs.length && inputs[i].amount == 0) {
- // there is a matching zero-valued input, eat it and use its color
- cur_color = inputs[i].color;
- ++i;
- } else {
- // there is no matching input so we cannot deduce zero-valued output's
- // color and thus use COLOR.MIXED
- cur_color = COLOR.MIXED;
- }
- }
-
- // color the output
- outputs[o].color = cur_color;
- cur_amount -= want_amount;
- }
-
- return true;
-}
-
-function validate_color_bands(inputs, errors) {
- // inputs of same color should be adjacent,
- // uncolored coins should go after colored.
-
- var seen_colors = {};
- var got_uncolored = false;
- var last_color = COLOR.UNKNOWN;
-
- for (var i = 0; i < inputs.length; ++i) {
- var c = inputs[i].color;
- if (c == COLOR.MIXED || c == COLOR.DEFAULT || c == COLOR.UNKNOWN) {
- got_uncolored = true;
- } else {
- if (got_uncolored) errors.uncolored_before_colored = true;
- if (c != last_color) {
- if (seen_colors[c])
- errors.color_band_broken = true;
- else
- seen_colors[c] = true;
- last_color = c;
- }
- }
- }
-}
-
-function validate_conservation(inputs, outputs, errors) {
- // check whether color conservation rule was violated.
- // besides general violation we try to detect two
- // particular cases:
- // * coins got mixed
- // * fee was paid with colored coins
-
- var input_color_amounts = {};
- var output_color_amounts = {};
-
- function getz(a, i) {
- var val = a[i];
- return val ? val : 0;
- }
-
- function sum_colors(points, sum) {
- var sum_uncolored = 0,
- sum_colored = 0;
- for (var i = 0; i < points.length; ++i) {
- var color = points[i].color,
- amount = points[i].amount;
-
- sum[color] = amount + getz(sum, color);
-
- if (uncolored(color))
- sum_uncolored += amount;
- else
- sum_colored += amount;
- }
- return {
- sum_uncolored: sum_uncolored,
- sum_colored: sum_colored
- };
- }
-
- var input = sum_colors(inputs, input_color_amounts);
- var output = sum_colors(outputs, output_color_amounts);
-
- for (var c in output_color_amounts) {
- if (!uncolored(c)) {
- if (getz(output_color_amounts, c) > getz(input_color_amounts, c))
- errors.conservation_gain = true;
- }
- }
-
- console.log(input_color_amounts);
-
- for (var c in input_color_amounts) {
- if (!uncolored(c)) {
- if (getz(output_color_amounts, c) < getz(input_color_amounts, c)) {
- console.log("loss: (" + c+ ") " + getz(output_color_amounts, c) + "<" + getz(input_color_amounts, c));
- errors.conservation_loss = true;
- }
- }
- }
-
-
- var mixed_delta = getz(output_color_amounts, COLOR.MIXED) - getz(input_color_amounts, COLOR.MIXED);
- var color_delta = output.sum_colored - input.sum_colored;
-
- if (mixed_delta > 0)
- errors.got_mixed = true;
-
- if (mixed_delta + color_delta < 0)
- errors.color_fee = true;
-}
-
-function validate_zero_valued(inputs, outputs, errors) {
- // one zero-valued input should match one zero-valued input
-
- var zv_inputs_count = {};
- var zv_outputs_count = {};
-
- function getz(a, i) {
- var val = a[i];
- return val ? val : 0;
- }
-
- function count_zv(points, count) {
- for (var i = 0; i < points.length; ++i) {
- if (points[i].amount == 0) {
- count[points[i].color] = 1 + getz(count, points[i].color);
- }
- }
- }
-
- count_zv(inputs, zv_inputs_count);
- count_zv(outputs, zv_outputs_count);
-
- for (var c in zv_inputs_count) {
- if (getz(zv_inputs_count, c) > getz(zv_outputs_count, c))
- errors.zero_input_mismatch = true;
- }
-
- for (var c in zv_outputs_count) {
- if (getz(zv_inputs_count, c) < getz(zv_outputs_count, c))
- errors.zero_output_mismatch = true;
- }
-}
-
-function compute_and_validate_colors(inputs, outputs) {
- var errors = {
- got_mixed: false,
- color_fee: false,
- zero_input_mismatch: false,
- zero_output_mismatch: false,
- uncolored_before_colored: false,
- color_band_broken: false,
- conservation_gain: false,
- conservation_loss: false
- };
- if (compute_colors(inputs, outputs)) {
- validate_color_bands(inputs, errors);
- validate_conservation(inputs, outputs, errors);
- validate_zero_valued(inputs, outputs, errors);
- return errors;
- } else return false;
-}
-
-function test_compute_colors() {
- var inputs = [{color: 1, amount:1},
- {color: 1, amount:2},
- {color: 2, amount:1},
- {color: 0, amount:3}];
- var outputs = [{color: -2, amount: 3},
- {color: -2, amount: 1},
- {color: -2, amount: 2}];
- var errors = compute_and_validate_colors(inputs, outputs);
- console.log(outputs);
- return errors;
-}
-test_compute_colors()
View
64 newcolor.js
@@ -0,0 +1,64 @@
+function colorOutputs(inputs, outputs) {
+ var apetite = 0
+ , tasted = 0
+ , eaten = 0
+
+ for (var i = 0, n = inputs.length; i < n ; ++ i){
+ apetite = inputs[i].amount
+ eaten = 0;
+ while (eaten < apetite && tasted < outputs.length){
+ outputs[tasted].color = inputs[i].color
+ console.log(outputs[tasted].color)
+ eaten += outputs[tasted].amount
+ ++tasted
+ }
+ }
+}
+
+function mergeColorInputs(inputs){
+ var mergeInputs = []
+ , i=0
+ , color = inputs[0].color
+ , amount = 0
+ , input
+
+ while (inputs.length > 0){
+ input = inputs.shift()
+ if (input.color == color){
+ amount += input.amount
+ } else {
+ mergeInputs.push(
+ { amount : amount
+ , color : color
+ }
+ )
+ amount = input.amount
+ color = input.color
+ }
+ }
+ mergeInputs.push(
+ { amount : amount
+ , color : color
+ }
+ )
+ return mergeInputs
+}
+
+var inputs = [{color: 'c1', amount:0.1}
+ ,{color: 'c1', amount:0.2}
+ ,{color: 'c2', amount:0.2}
+ ,{color: 'c3', amount:0.3}
+ ]
+
+var outputs = [{color: '', amount: 0.1}
+ ,{color: '', amount: 0.1}
+ ,{color: '', amount: 0.1}
+ ,{color: '', amount: 0.1}
+ ,{color: '', amount: 0.1}
+ ,{color: '', amount: 0.1}
+ ,{color: '', amount: 0.2}
+ ]
+
+inputs = mergeColorInputs(inputs)
+colorOutputs(inputs, outputs);
+console.log(outputs);
View
76 scanBlockChain.js
@@ -0,0 +1,76 @@
+var unspent = {"result":
+ [
+ {"txid":"577a123e7c34f401431659f66857b54bdf648ad8f508d3fc0a5b264f5ca19dca"
+ ,"vout":0
+ ,"scriptPubKey":"76a914b8f53423003b16a88430215e8aae5b97910a7b8d88ac"
+ ,"amount":0.02000000
+ ,"confirmations":21612
+ }
+ ,
+ {"txid":"eb5fdac5227d3ee32919932bf8e63a2b3aa3045dbb5fb2bfa8644fa5d544e00c"
+ ,"vout":1
+ ,"scriptPubKey":"76a91439359b758fc1d04ab3e426f2b12762ea0f44bb0288ac"
+ ,"amount":48.99000000
+ ,"confirmations":69873
+ }
+ ]
+,"error":null
+,"id":"t"
+}
+
+function getTx(prev_tx){
+
+}
+function getcoloringInputs(tx,output){
+
+}
+returnColor(input){
+ prev_tx_id = input.prev_tx
+ toAddr = input.sourceAddr
+ prev_tx = getTx(prev_tx_id)
+ while (prev_tx.out.length > 0){
+ output = prev_tx.out.shift()
+ if (output.toAddr == toAddr){
+ coloringInputs = getcoloringInputs(output)
+ color = 'undefined'
+ do{
+ prevInput = coloringInputs.shift()
+ var prevInputColor = returnColor(prevInput)
+ if (prevInputColor != color && color != 'undefined'){
+ color = 'mixed'
+ break
+ }
+ color = prevInputColor
+ } while (coloringInputs.length > 0){
+ return color
+ }
+ }
+}
+
+
+[ in: [{
+ sourceAddr: "16v13Fa9cPmfFzpm9mmbWwAkXY4gyY6uh4",
+ value: "0.03",
+ prev_tx: "f9e8d65db8d0b7934db6cff97c131d6048ebbfae52608b6b9795ef9db51bd7aa"
+ },
+ {
+ sourceAddr: "1GPwJvMpB4vJPuMwHs9JDAZm9Lh66Y2qnS",
+ value: "2.00",
+ prev_tx: "eae9c2a9770cb7c61244f96e5a1c8e4ef43e7cd077fbcee52f4a8803251bcd05"
+ },
+ {
+ sourceAddr: "1GPwJvMpB4vJPuMwHs9JDAZm9Lh66Y2qnS",
+ value: "34.00",
+ prev_tx: "81a39c41ca946d72e8b5de8ba61bbba085252a2b10f075dc1ca8d4118df4981e"
+ }
+]
+, out: [
+ {
+ toAddr: "129Y2z4gFA9ZzujNvnKoRiKWTHeSq8ZdYn",
+ value: "36.00"
+ },
+ {
+ toAddr: "1GPwJvMpB4vJPuMwHs9JDAZm9Lh66Y2qnS",
+ value: "0.03"
+ }
+]

0 comments on commit 236999e

Please sign in to comment.