-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathcip33_broadcast.html
197 lines (173 loc) · 7.22 KB
/
cip33_broadcast.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CIP33 - Broadcast File</title>
<link rel="stylesheet" href="css/main.css">
<script src="js/xcp/hex.js"></script>
<script src="js/xcp/assets.js"></script>
<script src="js/xcp/build_tx_msg.js"></script>
<script src="js/xcp/decode_tx_msg.js"></script>
<script src="js/xcp/display.js"></script>
<script src="js/xcp/rc4.js"></script>
<script src="js/xcp/validate_address.js"></script>
<script src="js/xcp/cip33.js"></script>
<script src="js/lib/bitcoinjs-lib.js"></script>
<script src="js/lib/bitcoinjs-message.js"></script>
<script src="js/lib/jquery-3.4.1.min.js"></script>
<script src="js/lib/lozad.min.js"></script>
<script src="js/lib/sha256.js"></script>
<script src="js/lib/btc.js"></script>
<script>
let addr = '';
let asset = '';
let longname = '';
let utxo = '';
let div = '';
let max = '';
let broadcast_text = '';
function get_url_parameters() {
//Get url parameter 'address'
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
if (urlParams.has('address')) {
addr = urlParams.get('address');
}
if (urlParams.has('utxo')) {
utxo = urlParams.get('utxo');
document.getElementById('input_utxo').value = utxo;
document.getElementById('div_utxo').style.display = 'none';
}
}
function display() {
let header = wallet_header;
header = header.replace('{address}', addr_short(addr));
if (utxo != '') {
header = header.replace('{utxo}', '<span onclick="document.getElementById(\'div_utxo\').style.display=\'block\';">UTXO '+utxo.slice(0,4)+'</span>');
} else{
header =header.replace('{utxo}', '');
}
document.getElementById('html_top').innerHTML = header;
}
function show_counter() {
let text = document.getElementById('input_text').value;
let hex = utf8_to_hex(text);
let counter = hex.length/2 + '/54';
document.getElementById('count_chars').innerHTML = counter;
}
function prepare_inputs() {
let network = document.getElementById("network").value;
let inp_utxo = document.getElementById('input_utxo').value; //eg a1870614c4cd1b3e20f98316f062c8622313eca4bbeb3f7bb695a61c164a45e7
let inp_tip_btc = document.getElementById('input_tip').value;
//Inputs formatted ok?
inp_utxo = inp_utxo.substring(0,64);
inp_utxo = inp_utxo.toLowerCase();
if (inp_utxo.length != 64) {
print_result("UTXO is not valid"); return;
}
let inp_len = utf8_to_hex(broadcast_text).length / 2;
if (inp_len > 54) {
print_result("File name is too long. Max 49 chars."); return; //54 minus 'FILE:' prefix
}
if (inp_len == 0) {
print_result("No file selected"); return;
}
if (isNaN(inp_tip_btc)) {
print_result("Tip is not a number"); return;
}
let out = ' ';
let opreturn_unencoded = msg_broadcast(broadcast_text);
console.log('Op_return unencoded: ' + opreturn_unencoded);
let opreturn = rc4_hex(inp_utxo, opreturn_unencoded);
//Sanity checks. Does decoded tx match inputs?
let info = decode_tx(opreturn, inp_utxo);
if (info.prefix != 'CNTRPRTY') {
print_result("Op_return encoding error. Wrong prefix."); return;
}
if (info.msg_id != 30) {
print_result("Op_return encoding error. Wrong messge ID."); return;
}
if (info.text != broadcast_text) {
print_result("Op_return encoding error. Wrong text."); return;
}
if (file_size == 0) {
print_result("File is empty."); return;
}
if (file_size > 6304) {//197 * 32 bytes
print_result("File is too large. Max size 6304 bytes."); return;
}
//Output messages and code
let sum_dust = 0;
let addresses = file_to_addresses(file_hex, network);
let code = 'OP_RETURN ' + opreturn + ',0';
for (let i = 0; i<addresses.length; i++) {
let dust = dust_limit + i
code += '\n' + addresses[i] + ',' + sat_to_btc(dust);
sum_dust += dust_limit + i;
}
if (network == 'bitcoin') {
code += tip_line(inp_tip_btc);
}
//Sanity check
if (file_hex != addresses_to_hex(addresses)) {
print_result("File or addresses encoding error."); return;
}
document.getElementById('warning_message').innerHTML = 'This transaction will forever save "' + file_name + '" on the blockchain.<br>₿' + sat_to_btc(sum_dust) + ' will get burnt.';
print_result(out, code)
}
function print_result(message = '', code = '') {
document.getElementById('text_output').innerHTML = '<br>' + message;
document.getElementById('code_output').innerHTML = code;
}
</script>
</head>
<body onload="get_url_parameters();display();">
<div id="content">
<div id="html_top"></div>
<h1>CIP33 – Broadcast File</h1>
<div>Store a file in a Bitcoin transaction (CIP33).</div><br>
<div id="div_network">Network<br>
<select name="network" id="network">
<option value="bitcoin">Bitcoin</option>
<option value="testnet">Testnet</option>
</select><br><br></div>
<div id="div_utxo">UTXO (Input Coin)<br>
<input id="input_utxo"><br><br></div>
<div id="div_file">File<br>
<input id="browseOpen" type="file" id="file-input" /><br><br></div>
<div id="div_tip">Optional Tip to Developer (BTC)<span id="suggested_tip" style="float:right" onclick="document.getElementById('input_tip').value='0.0001';">Suggested: 0.0001</span><br>
<input id="input_tip"><br></div>
<button type="button" id="generate" onclick="prepare_inputs();" >Generate Transaction</button><br><br>
<i><span style="font-size:75%" id="warning_message"> </span></i><br>
<span id="text_output"> <br> </span>
<textarea id="code_output" rows="5"></textarea>
<button type="button" id="copy" onclick="document.getElementById('code_output').select();document.execCommand('copy');">Copy</button><br><br>
</div>
</body>
<script>
document.getElementById('input_tip').value = tip_btc;
let file_hex = '';
let file_name = '';
let file_size = -1;
var fileInput = document.getElementById("browseOpen");
fileInput.onchange = function () {
file_hex = '';
var fr = new FileReader();
fr.onloadend = function () {
var result = this.result;
for (var i = 0; i < this.result.length; i++) {
var byteStr = result.charCodeAt(i).toString(16);
if (byteStr.length < 2) {
byteStr = "0" + byteStr;
}
file_hex += "" + byteStr;
}
//document.getElementById("input_text").value = 'FILE:' + file_name;
file_size = file_hex.length / 2;
broadcast_text= 'FILE:' + file_name;
};
fr.readAsBinaryString(this.files[0]);
file_name = this.files[0].name;
};
</script>
</html>