실습 - ODuck/FinTech GitHub Wiki

meteor plugins

  • Bootstrap
meteor add twbs:bootstrap
  • jQuery QR Code plugin
meteor add steeve:jquery-qrcode
  • Session Variable
meteor add session
  • http
meteor add http
  • qrcodesvg
meteor npm install qrcodesvg --save
  • bitcoin-address
meteor npm install bitcoin-address
  • meteor-node-stubs
meteor npm install meteor-node-stubs

sample code

client/main.html

<head>
<title>simple</title>
</head>

<body>{{> hello}}
</body>
<template name="hello">
<div class="container">
	<div class="header clearfix">
		<nav>
			<ul class="nav nav-pills pull-right">
				<li role="presentation" class="active"><a href="#">Home</a></li>
			</ul>
		</nav>
		<h3 class="text-muted">Bitcoin fountain</h3>
	</div>
	<div class="jumbotron">
		<center>
			<h3 id="pick_address">{{pickAddress}}</h3>
			<h1>비트코인 분수대</h1>
			<div id="qrcode"></div>
			<p class="lead">{{bitcoinAddress}}</p>
			<p>
				<button id="find" type="button" class="btn btn-primary">찾는다</button>
				<button id="pick" type="button" class="btn btn-primary">뽑는다.
					크큭</button>
				<button id="send" type="button" class="btn btn-primary">송금한다.
					크큭..</button>
			</p>
			<p>{{#if withdrawList}}
			<div class="table-responsive">
				<table class="table table-striped">
					<thead>
						<tr>
							<th>#</th>
							<th>TXID</th>
							<th>Value</th>
						</tr>
					</thead>
					<tbody>
						{{#each withdrawList}}
						<tr>
							<td></td>
							<td>{{transaction_hash}}</td>
							<td>{{value}} BTC</td>
						</tr>
						{{/each}}
					</tbody>
				</table>
			</div>
			{{/if}}
			</p>
		</center>
	</div>
	<footer class="footer">
		<p>&copy; 2016 Company, Inc.</p>
	</footer>
</div>
<!-- /container --> </template>
<template name="info">
<h2>Learn Meteor!</h2>
<ul>
	<li><a href="https://www.meteor.com/try">Do the Tutorial</a></li>
	<li><a href="http://guide.meteor.com">Follow the Guide</a></li>
	<li><a href="https://docs.meteor.com">Read the Docs</a></li>
	<li><a href="https://forums.meteor.com">Discussions</a></li>
</ul>
</template>

client/main.js

import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';

import './main.html';

var bitcoinPrivateKey = "";
var bitcoinAddress = "";

var accessKey = "80d1b821dcb89f965452de4ebbf7ae";
var secretKey = "55e2b5ac1bb4a0486b477926efa8bc";
client = new CoinStack(accessKey, secretKey);
withdrawList = new ReactiveVar(0);

Template.hello.onCreated(function helloOnCreated() {
    // counter starts at 0
    this.counter = new ReactiveVar(0);
});

Template.hello.onRendered(function helloOnRendered() {
    if (!this._rendered) {
        console.log('Template onLoad');
        this._rendered = true;

        $('#qrcode').qrcode({ width: 128, height: 128, text: "bitcoin:" + bitcoinAddress + "?amount=0.0001" });

        setInterval(checkBitcoinUnspentOutput, 2000);
    }
});

Template.hello.helpers({
    bitcoinAddress() {
        return bitcoinAddress;
    },
    withdrawList() {
        return Session.get('withdrawList');
    },
    pickAddress() {
        return Session.get('pickAddress');
    }
});

Template.hello.events({
    'click #find' (event, instance) {
        console.log('find');
        checkUnspentOutputsAddress();
    },
    'click #pick' (event, instance) {
        Session.set('pickAddress', _.sample(Session.get('addresses')));
        console.log('pick', Session.get('pickAddress'));
    },
    'click #send' (event, instance) {
        sendBitcoin();
    },
});

function checkBitcoinUnspentOutput() {
    client.getUnspentOutputs(bitcoinAddress, function(err, result) {
        var arrResult = _.map(result, function(element, index, list) {
            element.transaction_hash = CoinStack.Util.convertEndianness(element.transaction_hash);
            element.value = CoinStack.Math.toBitcoin(element.value);
            return element;
        });

        Session.set('withdrawList', _.sortBy(arrResult, 'confirmations'));
    });
}

function checkUnspentOutputsAddress() {
    Session.set('addresses', []);

    var arr = Session.get('withdrawList');

    for(var i=0; i<arr.length; i++){
        client.getTransaction(arr[i].transaction_hash, function(err, result) {
            console.log(result.inputs[0].address[0]);
            Session.set('addresses', Session.get('addresses').concat(result.inputs[0].address[0]));
        });
    }
}

function sendBitcoin() {
    console.log(Session.get('pickAddress'));

    var txBuilder = client.createTransactionBuilder();
    txBuilder.addOutput("TO_ADDRESS1", client.Math.toSatoshi("0.01"))
    txBuilder.setInput("MY_WALLET_ADDRESS");
    txBuilder.buildTransaction(function(err, tx) {
        tx.sign("MY_PRIVATE_KEY_WIF")
        var rawTx = tx.serialize()
        // send tx
        client.sendTransaction(rawTx, function(err) {
            if (null != err) {
                console.log("failed to send tx");
            } else {
                console.log("succeed broadcast");
            }
        });
    });
}
⚠️ **GitHub.com Fallback** ⚠️