Compare commits
No commits in common. "master" and "tokenswap-addition" have entirely different histories.
master
...
tokenswap-
32
.github/workflows/push-dappbundle.yml
vendored
32
.github/workflows/push-dappbundle.yml
vendored
@ -1,32 +0,0 @@
|
||||
name: Workflow push to Dappbundle
|
||||
on: [push]
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Executing remote command
|
||||
uses: appleboy/ssh-action@v1.0.0
|
||||
with:
|
||||
host: ${{ secrets.R_HOST }}
|
||||
username: ${{ secrets.P_USERNAME }}
|
||||
password: ${{ secrets.P_PASSWORD }}
|
||||
port: ${{ secrets.SSH_PORT }}
|
||||
script: |
|
||||
if [ -d "${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle" ]; then
|
||||
echo "Folder exists. Skipping Git clone."
|
||||
else
|
||||
echo "Folder does not exist. Cloning repository..."
|
||||
cd ${{ secrets.DEPLOYMENT_LOCATION}}/ && git clone https://github.com/ranchimall/dappbundle.git
|
||||
fi
|
||||
|
||||
if [ -d "${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle/${{ github.event.repository.name }}" ]; then
|
||||
echo "Repository exists. Remove folder "
|
||||
rm -r "${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle/${{ github.event.repository.name }}"
|
||||
fi
|
||||
|
||||
echo "Cloning repository..."
|
||||
cd ${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle && git clone https://github.com/ranchimall/${{ github.event.repository.name }}
|
||||
|
||||
cd "${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle/${{ github.event.repository.name }}" && rm -rf .gitattributes .git .github .gitignore
|
||||
cd ${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle/ && git add . && git commit -m "Workflow updating files of ${{ github.event.repository.name }}" && git push "https://ranchimalldev:${{ secrets.RM_ACCESS_TOKEN }}@github.com/ranchimall/dappbundle.git"
|
||||
42
README.md
42
README.md
@ -1,42 +1,2 @@
|
||||
# FLO Scout
|
||||
|
||||
FLO Scout is RanchiMall's token and smart contract explorer.
|
||||
All tokens, smart contracts, and their transactions (created on FLO blockchain) can be accessed on FLO Scout.
|
||||
|
||||
### Live URL for FLO Scout:
|
||||
*https://ranchimall.github.io/floscout/*
|
||||
|
||||
## How to use
|
||||
#### Search by address
|
||||
i) On the homepage of FLO Scout, enter the FLO address/FLO ID and press Enter
|
||||
ii) On the top it shows the FLO balance and the tokens and their respective balances of the FLO ID
|
||||
iii) Next it shows the token transfers, amount of token transferred, or smart contract transactions of the FLO address
|
||||
|
||||
#### Search by transaction
|
||||
i) Enter the transaction ID of a FLO blockchain token transfer in the search box
|
||||
ii) This will give the token transfer detail of that transaction, including sender and receiver address, FLO data, amount of token transfer, and timestamp of the transaction
|
||||
|
||||
#### Search by token name
|
||||
i) Enter the token name in the search box
|
||||
ii) This will give the incorporation address of the token (an incorporation address is the creator address of the token), the total supply of the token, all token transactions, and the details of token holders
|
||||
|
||||
#### Search by smart contract
|
||||
i) Enter the smart contract name in the search box
|
||||
ii) This will give the following details of the smart contract:
|
||||
a) Smart contract type (continuous, or one-time event)
|
||||
b) Smart contract subtype (tokenswap)
|
||||
c) Contract address (the FLO address that created the smart contract)
|
||||
d) Other statistics (no. of deposits, no. of participants, oracle address, total output, and total balance)
|
||||
e) Both off-chain and on-chain data
|
||||
f) Off-chain data is sub-transactions inside the smart contract
|
||||
|
||||
#### Search by block
|
||||
i) Enter the block number in the search box
|
||||
ii) This will give the following details of the block:
|
||||
a) Relevant Transactions (no. of transactions inside the block)
|
||||
b) No. of confirmations
|
||||
c) Reward
|
||||
d) Block Hash
|
||||
e) Difficulty
|
||||
f) Transactions (token transfer details)
|
||||
# flo scout
|
||||
|
||||
|
||||
2114
css/main.css
2114
css/main.css
File diff suppressed because it is too large
Load Diff
2
css/main.min.css
vendored
2
css/main.min.css
vendored
File diff suppressed because one or more lines are too long
1841
css/main.scss
1841
css/main.scss
File diff suppressed because it is too large
Load Diff
11
floscout.svg
11
floscout.svg
@ -1,11 +0,0 @@
|
||||
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_3_34)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M50.5679 101.136C78.4958 101.136 101.136 78.4958 101.136 50.5679C101.136 47.0696 100.781 43.6543 100.104 40.3561C104.75 47.3575 107.457 55.7578 107.457 64.7901C107.457 89.227 87.6468 109.037 63.2099 109.037C52.318 109.037 42.3453 105.102 34.6362 98.575C39.6451 100.236 45.0015 101.136 50.5679 101.136ZM34.6362 98.575C14.5144 91.9008 0 72.9293 0 50.5679C0 22.64 22.64 0 50.5679 0C74.9975 0 95.381 17.3234 100.104 40.3561C92.1803 28.4153 78.6144 20.5432 63.2099 20.5432C38.773 20.5432 18.963 40.3532 18.963 64.7901C18.963 78.3351 25.0492 90.4586 34.6362 98.575Z" fill="#4F56FF"/>
|
||||
<circle cx="113.333" cy="113.333" r="14.6667" fill="#4F56FF"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_3_34">
|
||||
<rect width="128" height="128" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 934 B |
6452
index.html
6452
index.html
File diff suppressed because it is too large
Load Diff
10
scripts/components.min.js
vendored
10
scripts/components.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,44 +0,0 @@
|
||||
/**!
|
||||
* FlexSearch.js v0.7.31 (Light)
|
||||
* Copyright 2018-2022 Nextapps GmbH
|
||||
* Author: Thomas Wilkerling
|
||||
* Licence: Apache-2.0
|
||||
* https://github.com/nextapps-de/flexsearch
|
||||
*/
|
||||
(function (self) {
|
||||
'use strict'; function t(a) { return "undefined" !== typeof a ? a : !0 } function v(a) { const c = Array(a); for (let b = 0; b < a; b++)c[b] = y(); return c } function y() { return Object.create(null) } function z(a, c) { return c.length - a.length }; const A = /[\p{Z}\p{S}\p{P}\p{C}]+/u; function B(a, c) { const b = Object.keys(a), d = b.length, e = []; let h = "", f = 0; for (let g = 0, l, n; g < d; g++)l = b[g], (n = a[l]) ? (e[f++] = new RegExp(c ? "(?!\\b)" + l + "(\\b|_)" : l, "g"), e[f++] = n) : h += (h ? "|" : "") + l; h && (e[f++] = new RegExp(c ? "(?!\\b)(" + h + ")(\\b|_)" : "(" + h + ")", "g"), e[f] = ""); return e } function C(a, c) { for (let b = 0, d = c.length; b < d && (a = a.replace(c[b], c[b + 1]), a); b += 2); return a }; function D(a) { if (a = ("" + a).toLowerCase()) if (this.o && (a = C(a, this.o)), this.A && 1 < a.length && (a = C(a, this.A)), A || "" === A) if (a = a.split(A), this.filter) { var c = this.filter; const b = a.length, d = []; for (let e = 0, h = 0; e < b; e++) { const f = a[e]; f && !c[f] && (d[h++] = f) } a = d } return a }; const F = {}, G = {}; function H(a, c, b, d) {
|
||||
const e = a.length; let h = [], f, g, l = 0; d && (d = []); for (let n = e - 1; 0 <= n; n--) { const m = a[n], r = m.length, p = y(); let q = !f; for (let k = 0; k < r; k++) { const u = m[k], M = u.length; if (M) for (let E = 0, x, w; E < M; E++)if (w = u[E], f) { if (f[w]) { if (!n) if (b) b--; else if (h[l++] = w, l === c) return h; if (n || d) p[w] = 1; q = !0 } if (d && (x = (g[w] || 0) + 1, g[w] = x, x < e)) { const N = d[x - 2] || (d[x - 2] = []); N[N.length] = w } } else p[w] = 1 } if (d) f || (g = p); else if (!q) return []; f = p } if (d) for (let n = d.length - 1, m, r; 0 <= n; n--) {
|
||||
m = d[n]; r = m.length; for (let p = 0, q; p < r; p++)if (q =
|
||||
m[p], !f[q]) { if (b) b--; else if (h[l++] = q, l === c) return h; f[q] = 1 }
|
||||
} return h
|
||||
}; function I(a, c) {
|
||||
if (!(this instanceof I)) return new I(a); let b; if (a) { var d = a.charset; b = a.lang; "string" === typeof d && (-1 === d.indexOf(":") && (d += ":default"), d = G[d]); "string" === typeof b && (b = F[b]) } else a = {}; let e, h, f = a.context || {}; this.encode = a.encode || d && d.encode || D; this.register = c || y(); this.s = e = a.resolution || 9; this.B = c = d && d.B || a.tokenize || "strict"; this.i = "strict" === c && f.depth; this.j = t(f.bidirectional); this.g = h = t(a.optimize); this.m = t(a.fastupdate); this.h = a.minlength || 1; this.C = a.boost; this.map = h ? v(e) : y();
|
||||
this.v = e = f.resolution || 1; this.l = h ? v(e) : y(); this.u = d && d.u || a.rtl; this.o = (c = a.matcher || b && b.o) && B(c, !1); this.A = (c = a.stemmer || b && b.A) && B(c, !0); if (a = c = a.filter || b && b.filter) { a = c; d = y(); for (let g = 0, l = a.length; g < l; g++)d[a[g]] = 1; a = d } this.filter = a
|
||||
} I.prototype.append = function (a, c) { return this.add(a, c, !0) };
|
||||
I.prototype.add = function (a, c, b, d) {
|
||||
if (c && (a || 0 === a)) {
|
||||
if (!d && !b && this.register[a]) return this.update(a, c); c = this.encode(c); if (d = c.length) {
|
||||
const n = y(), m = y(), r = this.i, p = this.s; for (let q = 0; q < d; q++) {
|
||||
let k = c[this.u ? d - 1 - q : q]; var e = k.length; if (k && e >= this.h && (r || !m[k])) {
|
||||
var h = J(p, d, q), f = ""; switch (this.B) {
|
||||
case "full": if (2 < e) { for (h = 0; h < e; h++)for (var g = e; g > h; g--)if (g - h >= this.h) { var l = J(p, d, q, e, h); f = k.substring(h, g); K(this, m, f, l, a, b) } break } case "reverse": if (1 < e) {
|
||||
for (g = e - 1; 0 < g; g--)f = k[g] + f, f.length >= this.h && K(this,
|
||||
m, f, J(p, d, q, e, g), a, b); f = ""
|
||||
} case "forward": if (1 < e) { for (g = 0; g < e; g++)f += k[g], f.length >= this.h && K(this, m, f, h, a, b); break } default: if (this.C && (h = Math.min(h / this.C(c, k, q) | 0, p - 1)), K(this, m, k, h, a, b), r && 1 < d && q < d - 1) for (e = y(), f = this.v, h = k, g = Math.min(r + 1, d - q), e[h] = 1, l = 1; l < g; l++)if ((k = c[this.u ? d - 1 - q - l : q + l]) && k.length >= this.h && !e[k]) { e[k] = 1; const u = this.j && k > h; K(this, n, u ? h : k, J(f + (d / 2 > f ? 0 : 1), d, q, g - 1, l - 1), a, b, u ? k : h) }
|
||||
}
|
||||
}
|
||||
} this.m || (this.register[a] = 1)
|
||||
}
|
||||
} return this
|
||||
};
|
||||
function J(a, c, b, d, e) { return b && 1 < a ? c + (d || 0) <= a ? b + (e || 0) : (a - 1) / (c + (d || 0)) * (b + (e || 0)) + 1 | 0 : 0 } function K(a, c, b, d, e, h, f) { let g = f ? a.l : a.map; if (!c[b] || f && !c[b][f]) a.g && (g = g[d]), f ? (c = c[b] || (c[b] = y()), c[f] = 1, g = g[f] || (g[f] = y())) : c[b] = 1, g = g[b] || (g[b] = []), a.g || (g = g[d] || (g[d] = [])), h && g.includes(e) || (g[g.length] = e, a.m && (a = a.register[e] || (a.register[e] = []), a[a.length] = g)) }
|
||||
I.prototype.search = function (a, c, b) {
|
||||
b || (c || "object" !== typeof a ? "object" === typeof c && (b = c) : (b = a, a = b.query)); let d = [], e; let h, f = 0; if (b) { a = b.query || a; c = b.limit; f = b.offset || 0; var g = b.context; h = !1 } if (a && (a = this.encode("" + a), e = a.length, 1 < e)) { b = y(); var l = []; for (let m = 0, r = 0, p; m < e; m++)if ((p = a[m]) && p.length >= this.h && !b[p]) if (this.g || h || this.map[p]) l[r++] = p, b[p] = 1; else return d; a = l; e = a.length } if (!e) return d; c || (c = 100); g = this.i && 1 < e && !1 !== g; b = 0; let n; g ? (n = a[0], b = 1) : 1 < e && a.sort(z); for (let m, r; b < e; b++) {
|
||||
r = a[b]; g ?
|
||||
(m = L(this, d, h, c, f, 2 === e, r, n), h && !1 === m && d.length || (n = r)) : m = L(this, d, h, c, f, 1 === e, r); if (m) return m; if (h && b === e - 1) { l = d.length; if (!l) { if (g) { g = 0; b = -1; continue } return d } if (1 === l) return O(d[0], c, f) }
|
||||
} return H(d, c, f, h)
|
||||
};
|
||||
function L(a, c, b, d, e, h, f, g) { let l = [], n = g ? a.l : a.map; a.g || (n = P(n, f, g, a.j)); if (n) { let m = 0; const r = Math.min(n.length, g ? a.v : a.s); for (let p = 0, q = 0, k, u; p < r; p++)if (k = n[p]) if (a.g && (k = P(k, f, g, a.j)), e && k && h && (u = k.length, u <= e ? (e -= u, k = null) : (k = k.slice(e), e = 0)), k && (l[m++] = k, h && (q += k.length, q >= d))) break; if (m) { if (h) return O(l, d, 0); c[c.length] = l; return } } return !b && l } function O(a, c, b) { a = 1 === a.length ? a[0] : [].concat.apply([], a); return b || a.length > c ? a.slice(b, b + c) : a }
|
||||
function P(a, c, b, d) { b ? (d = d && c > b, a = (a = a[d ? c : b]) && a[d ? b : c]) : a = a[c]; return a } I.prototype.contain = function (a) { return !!this.register[a] }; I.prototype.update = function (a, c) { return this.remove(a).add(a, c) }; I.prototype.remove = function (a, c) { const b = this.register[a]; if (b) { if (this.m) for (let d = 0, e; d < b.length; d++)e = b[d], e.splice(e.indexOf(a), 1); else Q(this.map, a, this.s, this.g), this.i && Q(this.l, a, this.v, this.g); c || delete this.register[a] } return this };
|
||||
function Q(a, c, b, d, e) { let h = 0; if (a.constructor === Array) if (e) c = a.indexOf(c), -1 !== c ? 1 < a.length && (a.splice(c, 1), h++) : h++; else { e = Math.min(a.length, b); for (let f = 0, g; f < e; f++)if (g = a[f]) h = Q(g, c, b, d, e), d || h || delete a[f] } else for (let f in a) (h = Q(a[f], c, b, d, e)) || delete a[f]; return h }; const R = self; let S; const T = { Index: I, Document: null, Worker: null, registerCharset: function (a, c) { G[a] = c }, registerLanguage: function (a, c) { F[a] = c } }; (S = R.define) && S.amd ? S([], function () { return T }) : R.exports ? R.exports = T : R.FlexSearch = T;
|
||||
}(this));
|
||||
File diff suppressed because one or more lines are too long
1
scripts/floBlockchainAPI.min.js
vendored
1
scripts/floBlockchainAPI.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,530 +0,0 @@
|
||||
(function (EXPORTS) { //floCrypto v2.3.6a
|
||||
/* FLO Crypto Operators */
|
||||
'use strict';
|
||||
const floCrypto = EXPORTS;
|
||||
|
||||
const p = BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
|
||||
const ecparams = EllipticCurve.getSECCurveByName("secp256k1");
|
||||
const ascii_alternatives = `‘ '\n’ '\n“ "\n” "\n– --\n— ---\n≥ >=\n≤ <=\n≠ !=\n× *\n÷ /\n← <-\n→ ->\n↔ <->\n⇒ =>\n⇐ <=\n⇔ <=>`;
|
||||
const exponent1 = () => p.add(BigInteger.ONE).divide(BigInteger("4"));
|
||||
coinjs.compressed = true; //defaulting coinjs compressed to true;
|
||||
|
||||
function calculateY(x) {
|
||||
let exp = exponent1();
|
||||
// x is x value of public key in BigInteger format without 02 or 03 or 04 prefix
|
||||
return x.modPow(BigInteger("3"), p).add(BigInteger("7")).mod(p).modPow(exp, p)
|
||||
}
|
||||
|
||||
function getUncompressedPublicKey(compressedPublicKey) {
|
||||
// Fetch x from compressedPublicKey
|
||||
let pubKeyBytes = Crypto.util.hexToBytes(compressedPublicKey);
|
||||
const prefix = pubKeyBytes.shift() // remove prefix
|
||||
let prefix_modulus = prefix % 2;
|
||||
pubKeyBytes.unshift(0) // add prefix 0
|
||||
let x = new BigInteger(pubKeyBytes)
|
||||
let xDecimalValue = x.toString()
|
||||
// Fetch y
|
||||
let y = calculateY(x);
|
||||
let yDecimalValue = y.toString();
|
||||
// verify y value
|
||||
let resultBigInt = y.mod(BigInteger("2"));
|
||||
let check = resultBigInt.toString() % 2;
|
||||
if (prefix_modulus !== check)
|
||||
yDecimalValue = y.negate().mod(p).toString();
|
||||
return {
|
||||
x: xDecimalValue,
|
||||
y: yDecimalValue
|
||||
};
|
||||
}
|
||||
|
||||
function getSenderPublicKeyString() {
|
||||
let privateKey = ellipticCurveEncryption.senderRandom();
|
||||
var senderPublicKeyString = ellipticCurveEncryption.senderPublicString(privateKey);
|
||||
return {
|
||||
privateKey: privateKey,
|
||||
senderPublicKeyString: senderPublicKeyString
|
||||
}
|
||||
}
|
||||
|
||||
function deriveSharedKeySender(receiverPublicKeyHex, senderPrivateKey) {
|
||||
let receiverPublicKeyString = getUncompressedPublicKey(receiverPublicKeyHex);
|
||||
var senderDerivedKey = ellipticCurveEncryption.senderSharedKeyDerivation(
|
||||
receiverPublicKeyString.x, receiverPublicKeyString.y, senderPrivateKey);
|
||||
return senderDerivedKey;
|
||||
}
|
||||
|
||||
function deriveSharedKeyReceiver(senderPublicKeyString, receiverPrivateKey) {
|
||||
return ellipticCurveEncryption.receiverSharedKeyDerivation(
|
||||
senderPublicKeyString.XValuePublicString, senderPublicKeyString.YValuePublicString, receiverPrivateKey);
|
||||
}
|
||||
|
||||
function getReceiverPublicKeyString(privateKey) {
|
||||
return ellipticCurveEncryption.receiverPublicString(privateKey);
|
||||
}
|
||||
|
||||
function wifToDecimal(pk_wif, isPubKeyCompressed = false) {
|
||||
let pk = Bitcoin.Base58.decode(pk_wif)
|
||||
pk.shift()
|
||||
pk.splice(-4, 4)
|
||||
//If the private key corresponded to a compressed public key, also drop the last byte (it should be 0x01).
|
||||
if (isPubKeyCompressed == true) pk.pop()
|
||||
pk.unshift(0)
|
||||
let privateKeyDecimal = BigInteger(pk).toString()
|
||||
let privateKeyHex = Crypto.util.bytesToHex(pk)
|
||||
return {
|
||||
privateKeyDecimal: privateKeyDecimal,
|
||||
privateKeyHex: privateKeyHex
|
||||
}
|
||||
}
|
||||
|
||||
//generate a random Interger within range
|
||||
floCrypto.randInt = function (min, max) {
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(securedMathRandom() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
//generate a random String within length (options : alphaNumeric chars only)
|
||||
floCrypto.randString = function (length, alphaNumeric = true) {
|
||||
var result = '';
|
||||
var characters = alphaNumeric ? 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' :
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_+-./*?@#&$<>=[]{}():';
|
||||
for (var i = 0; i < length; i++)
|
||||
result += characters.charAt(Math.floor(securedMathRandom() * characters.length));
|
||||
return result;
|
||||
}
|
||||
|
||||
//Encrypt Data using public-key
|
||||
floCrypto.encryptData = function (data, receiverPublicKeyHex) {
|
||||
var senderECKeyData = getSenderPublicKeyString();
|
||||
var senderDerivedKey = deriveSharedKeySender(receiverPublicKeyHex, senderECKeyData.privateKey);
|
||||
let senderKey = senderDerivedKey.XValue + senderDerivedKey.YValue;
|
||||
let secret = Crypto.AES.encrypt(data, senderKey);
|
||||
return {
|
||||
secret: secret,
|
||||
senderPublicKeyString: senderECKeyData.senderPublicKeyString
|
||||
};
|
||||
}
|
||||
|
||||
//Decrypt Data using private-key
|
||||
floCrypto.decryptData = function (data, privateKeyHex) {
|
||||
var receiverECKeyData = {};
|
||||
if (typeof privateKeyHex !== "string") throw new Error("No private key found.");
|
||||
let privateKey = wifToDecimal(privateKeyHex, true);
|
||||
if (typeof privateKey.privateKeyDecimal !== "string") throw new Error("Failed to detremine your private key.");
|
||||
receiverECKeyData.privateKey = privateKey.privateKeyDecimal;
|
||||
var receiverDerivedKey = deriveSharedKeyReceiver(data.senderPublicKeyString, receiverECKeyData.privateKey);
|
||||
let receiverKey = receiverDerivedKey.XValue + receiverDerivedKey.YValue;
|
||||
let decryptMsg = Crypto.AES.decrypt(data.secret, receiverKey);
|
||||
return decryptMsg;
|
||||
}
|
||||
|
||||
//Sign data using private-key
|
||||
floCrypto.signData = function (data, privateKeyHex) {
|
||||
var key = new Bitcoin.ECKey(privateKeyHex);
|
||||
var messageHash = Crypto.SHA256(data);
|
||||
var messageSign = Bitcoin.ECDSA.sign(messageHash, key.priv);
|
||||
var sighex = Crypto.util.bytesToHex(messageSign);
|
||||
return sighex;
|
||||
}
|
||||
|
||||
//Verify signatue of the data using public-key
|
||||
floCrypto.verifySign = function (data, signatureHex, publicKeyHex) {
|
||||
var msgHash = Crypto.SHA256(data);
|
||||
var sigBytes = Crypto.util.hexToBytes(signatureHex);
|
||||
var publicKeyPoint = ecparams.getCurve().decodePointHex(publicKeyHex);
|
||||
var verify = Bitcoin.ECDSA.verify(msgHash, sigBytes, publicKeyPoint);
|
||||
return verify;
|
||||
}
|
||||
|
||||
//Generates a new flo ID and returns private-key, public-key and floID
|
||||
const generateNewID = floCrypto.generateNewID = function () {
|
||||
var key = new Bitcoin.ECKey(false);
|
||||
key.setCompressed(true);
|
||||
return {
|
||||
floID: key.getBitcoinAddress(),
|
||||
pubKey: key.getPubKeyHex(),
|
||||
privKey: key.getBitcoinWalletImportFormat()
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperties(floCrypto, {
|
||||
newID: {
|
||||
get: () => generateNewID()
|
||||
},
|
||||
hashID: {
|
||||
value: (str) => {
|
||||
let bytes = ripemd160(Crypto.SHA256(str, { asBytes: true }), { asBytes: true });
|
||||
bytes.unshift(bitjs.pub);
|
||||
var hash = Crypto.SHA256(Crypto.SHA256(bytes, {
|
||||
asBytes: true
|
||||
}), {
|
||||
asBytes: true
|
||||
});
|
||||
var checksum = hash.slice(0, 4);
|
||||
return bitjs.Base58.encode(bytes.concat(checksum));
|
||||
}
|
||||
},
|
||||
tmpID: {
|
||||
get: () => {
|
||||
let bytes = Crypto.util.randomBytes(20);
|
||||
bytes.unshift(bitjs.pub);
|
||||
var hash = Crypto.SHA256(Crypto.SHA256(bytes, {
|
||||
asBytes: true
|
||||
}), {
|
||||
asBytes: true
|
||||
});
|
||||
var checksum = hash.slice(0, 4);
|
||||
return bitjs.Base58.encode(bytes.concat(checksum));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//Returns public-key from private-key
|
||||
floCrypto.getPubKeyHex = function (privateKeyHex) {
|
||||
if (!privateKeyHex)
|
||||
return null;
|
||||
var key = new Bitcoin.ECKey(privateKeyHex);
|
||||
if (key.priv == null)
|
||||
return null;
|
||||
key.setCompressed(true);
|
||||
return key.getPubKeyHex();
|
||||
}
|
||||
|
||||
//Returns flo-ID from public-key or private-key
|
||||
floCrypto.getFloID = function (keyHex) {
|
||||
if (!keyHex)
|
||||
return null;
|
||||
try {
|
||||
var key = new Bitcoin.ECKey(keyHex);
|
||||
if (key.priv == null)
|
||||
key.setPub(keyHex);
|
||||
return key.getBitcoinAddress();
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
floCrypto.getAddress = function (privateKeyHex, strict = false) {
|
||||
if (!privateKeyHex)
|
||||
return;
|
||||
var key = new Bitcoin.ECKey(privateKeyHex);
|
||||
if (key.priv == null)
|
||||
return null;
|
||||
key.setCompressed(true);
|
||||
let pubKey = key.getPubKeyHex(),
|
||||
version = bitjs.Base58.decode(privateKeyHex)[0];
|
||||
switch (version) {
|
||||
case coinjs.priv: //BTC
|
||||
return coinjs.bech32Address(pubKey).address;
|
||||
case bitjs.priv: //FLO
|
||||
return bitjs.pubkey2address(pubKey);
|
||||
default:
|
||||
return strict ? false : bitjs.pubkey2address(pubKey); //default to FLO address (if strict=false)
|
||||
}
|
||||
}
|
||||
|
||||
//Verify the private-key for the given public-key or flo-ID
|
||||
floCrypto.verifyPrivKey = function (privateKeyHex, pubKey_floID, isfloID = true) {
|
||||
if (!privateKeyHex || !pubKey_floID)
|
||||
return false;
|
||||
try {
|
||||
var key = new Bitcoin.ECKey(privateKeyHex);
|
||||
if (key.priv == null)
|
||||
return false;
|
||||
key.setCompressed(true);
|
||||
if (isfloID && pubKey_floID == key.getBitcoinAddress())
|
||||
return true;
|
||||
else if (!isfloID && pubKey_floID.toUpperCase() == key.getPubKeyHex().toUpperCase())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
floCrypto.getMultisigAddress = function (publicKeyList, requiredSignatures) {
|
||||
if (!Array.isArray(publicKeyList) || !publicKeyList.length)
|
||||
return null;
|
||||
if (!Number.isInteger(requiredSignatures) || requiredSignatures < 1 || requiredSignatures > publicKeyList.length)
|
||||
return null;
|
||||
try {
|
||||
var multisig = bitjs.pubkeys2multisig(publicKeyList, requiredSignatures);
|
||||
return multisig;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
floCrypto.decodeRedeemScript = function (redeemScript) {
|
||||
try {
|
||||
var decoded = bitjs.transaction().decodeRedeemScript(redeemScript);
|
||||
return decoded;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//Check if the given flo-id is valid or not
|
||||
floCrypto.validateFloID = function (floID, regularOnly = false) {
|
||||
if (!floID)
|
||||
return false;
|
||||
try {
|
||||
let addr = new Bitcoin.Address(floID);
|
||||
if (regularOnly && addr.version != Bitcoin.Address.standardVersion)
|
||||
return false;
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Check if the given address (any blockchain) is valid or not
|
||||
floCrypto.validateAddr = function (address, std = true, bech = true) {
|
||||
let raw = decodeAddress(address);
|
||||
if (!raw)
|
||||
return false;
|
||||
if (typeof raw.version !== 'undefined') { //legacy or segwit
|
||||
if (std == false)
|
||||
return false;
|
||||
else if (std === true || (!Array.isArray(std) && std === raw.version) || (Array.isArray(std) && std.includes(raw.version)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
} else if (typeof raw.bech_version !== 'undefined') { //bech32
|
||||
if (bech === false)
|
||||
return false;
|
||||
else if (bech === true || (!Array.isArray(bech) && bech === raw.bech_version) || (Array.isArray(bech) && bech.includes(raw.bech_version)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
} else //unknown
|
||||
return false;
|
||||
}
|
||||
|
||||
//Check the public-key (or redeem-script) for the address (any blockchain)
|
||||
floCrypto.verifyPubKey = function (pubKeyHex, address) {
|
||||
let raw = decodeAddress(address);
|
||||
if (!raw)
|
||||
return;
|
||||
let pub_hash = Crypto.util.bytesToHex(ripemd160(Crypto.SHA256(Crypto.util.hexToBytes(pubKeyHex), { asBytes: true })));
|
||||
if (typeof raw.bech_version !== 'undefined' && raw.bytes.length == 32) //bech32-multisig
|
||||
raw.hex = Crypto.util.bytesToHex(ripemd160(raw.bytes, { asBytes: true }));
|
||||
return pub_hash === raw.hex;
|
||||
}
|
||||
|
||||
//Convert the given address (any blockchain) to equivalent floID
|
||||
floCrypto.toFloID = function (address, options = null) {
|
||||
if (!address)
|
||||
return;
|
||||
let raw = decodeAddress(address);
|
||||
if (!raw)
|
||||
return;
|
||||
else if (options) { //if (optional) version check is passed
|
||||
if (typeof raw.version !== 'undefined' && (!options.std || !options.std.includes(raw.version)))
|
||||
return;
|
||||
if (typeof raw.bech_version !== 'undefined' && (!options.bech || !options.bech.includes(raw.bech_version)))
|
||||
return;
|
||||
}
|
||||
raw.bytes.unshift(bitjs.pub);
|
||||
let hash = Crypto.SHA256(Crypto.SHA256(raw.bytes, {
|
||||
asBytes: true
|
||||
}), {
|
||||
asBytes: true
|
||||
});
|
||||
return bitjs.Base58.encode(raw.bytes.concat(hash.slice(0, 4)));
|
||||
}
|
||||
|
||||
//Convert raw address bytes to floID
|
||||
floCrypto.rawToFloID = function (raw_bytes) {
|
||||
if (typeof raw_bytes === 'string')
|
||||
raw_bytes = Crypto.util.hexToBytes(raw_bytes);
|
||||
if (raw_bytes.length != 20)
|
||||
return null;
|
||||
raw_bytes.unshift(bitjs.pub);
|
||||
let hash = Crypto.SHA256(Crypto.SHA256(raw_bytes, {
|
||||
asBytes: true
|
||||
}), {
|
||||
asBytes: true
|
||||
});
|
||||
return bitjs.Base58.encode(raw_bytes.concat(hash.slice(0, 4)));
|
||||
}
|
||||
|
||||
//Convert the given multisig address (any blockchain) to equivalent multisig floID
|
||||
floCrypto.toMultisigFloID = function (address, options = null) {
|
||||
if (!address)
|
||||
return;
|
||||
let raw = decodeAddress(address);
|
||||
if (!raw)
|
||||
return;
|
||||
else if (options) { //if (optional) version check is passed
|
||||
if (typeof raw.version !== 'undefined' && (!options.std || !options.std.includes(raw.version)))
|
||||
return;
|
||||
if (typeof raw.bech_version !== 'undefined' && (!options.bech || !options.bech.includes(raw.bech_version)))
|
||||
return;
|
||||
}
|
||||
if (typeof raw.bech_version !== 'undefined') {
|
||||
if (raw.bytes.length != 32) return; //multisig bech address have 32 bytes
|
||||
//multisig-bech:hash=SHA256 whereas multisig:hash=r160(SHA265), thus ripemd160 the bytes from multisig-bech
|
||||
raw.bytes = ripemd160(raw.bytes, {
|
||||
asBytes: true
|
||||
});
|
||||
}
|
||||
raw.bytes.unshift(bitjs.multisig);
|
||||
let hash = Crypto.SHA256(Crypto.SHA256(raw.bytes, {
|
||||
asBytes: true
|
||||
}), {
|
||||
asBytes: true
|
||||
});
|
||||
return bitjs.Base58.encode(raw.bytes.concat(hash.slice(0, 4)));
|
||||
}
|
||||
|
||||
//Checks if the given addresses (any blockchain) are same (w.r.t keys)
|
||||
floCrypto.isSameAddr = function (addr1, addr2) {
|
||||
if (!addr1 || !addr2)
|
||||
return;
|
||||
let raw1 = decodeAddress(addr1),
|
||||
raw2 = decodeAddress(addr2);
|
||||
if (!raw1 || !raw2)
|
||||
return false;
|
||||
else {
|
||||
if (typeof raw1.bech_version !== 'undefined' && raw1.bytes.length == 32) //bech32-multisig
|
||||
raw1.hex = Crypto.util.bytesToHex(ripemd160(raw1.bytes, { asBytes: true }));
|
||||
if (typeof raw2.bech_version !== 'undefined' && raw2.bytes.length == 32) //bech32-multisig
|
||||
raw2.hex = Crypto.util.bytesToHex(ripemd160(raw2.bytes, { asBytes: true }));
|
||||
return raw1.hex === raw2.hex;
|
||||
}
|
||||
}
|
||||
|
||||
const decodeAddress = floCrypto.decodeAddr = function (address) {
|
||||
if (!address)
|
||||
return;
|
||||
else if (address.length == 33 || address.length == 34) { //legacy encoding
|
||||
let decode = bitjs.Base58.decode(address);
|
||||
let bytes = decode.slice(0, decode.length - 4);
|
||||
let checksum = decode.slice(decode.length - 4),
|
||||
hash = Crypto.SHA256(Crypto.SHA256(bytes, {
|
||||
asBytes: true
|
||||
}), {
|
||||
asBytes: true
|
||||
});
|
||||
return (hash[0] != checksum[0] || hash[1] != checksum[1] || hash[2] != checksum[2] || hash[3] != checksum[3]) ? null : {
|
||||
version: bytes.shift(),
|
||||
hex: Crypto.util.bytesToHex(bytes),
|
||||
bytes
|
||||
}
|
||||
} else if (address.length == 42 || address.length == 62) { //bech encoding
|
||||
let decode = coinjs.bech32_decode(address);
|
||||
if (decode) {
|
||||
let bytes = decode.data;
|
||||
let bech_version = bytes.shift();
|
||||
bytes = coinjs.bech32_convert(bytes, 5, 8, false);
|
||||
return {
|
||||
bech_version,
|
||||
hrp: decode.hrp,
|
||||
hex: Crypto.util.bytesToHex(bytes),
|
||||
bytes
|
||||
}
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//Split the str using shamir's Secret and Returns the shares
|
||||
floCrypto.createShamirsSecretShares = function (str, total_shares, threshold_limit) {
|
||||
try {
|
||||
if (str.length > 0) {
|
||||
var strHex = shamirSecretShare.str2hex(str);
|
||||
var shares = shamirSecretShare.share(strHex, total_shares, threshold_limit);
|
||||
return shares;
|
||||
}
|
||||
return false;
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
//Returns the retrived secret by combining the shamirs shares
|
||||
const retrieveShamirSecret = floCrypto.retrieveShamirSecret = function (sharesArray) {
|
||||
try {
|
||||
if (sharesArray.length > 0) {
|
||||
var comb = shamirSecretShare.combine(sharesArray.slice(0, sharesArray.length));
|
||||
comb = shamirSecretShare.hex2str(comb);
|
||||
return comb;
|
||||
}
|
||||
return false;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//Verifies the shares and str
|
||||
floCrypto.verifyShamirsSecret = function (sharesArray, str) {
|
||||
if (!str)
|
||||
return null;
|
||||
else if (retrieveShamirSecret(sharesArray) === str)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
const validateASCII = floCrypto.validateASCII = function (string, bool = true) {
|
||||
if (typeof string !== "string")
|
||||
return null;
|
||||
if (bool) {
|
||||
let x;
|
||||
for (let i = 0; i < string.length; i++) {
|
||||
x = string.charCodeAt(i);
|
||||
if (x < 32 || x > 127)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
let x, invalids = {};
|
||||
for (let i = 0; i < string.length; i++) {
|
||||
x = string.charCodeAt(i);
|
||||
if (x < 32 || x > 127)
|
||||
if (x in invalids)
|
||||
invalids[string[i]].push(i)
|
||||
else
|
||||
invalids[string[i]] = [i];
|
||||
}
|
||||
if (Object.keys(invalids).length)
|
||||
return invalids;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
floCrypto.convertToASCII = function (string, mode = 'soft-remove') {
|
||||
let chars = validateASCII(string, false);
|
||||
if (chars === true)
|
||||
return string;
|
||||
else if (chars === null)
|
||||
return null;
|
||||
let convertor, result = string,
|
||||
refAlt = {};
|
||||
ascii_alternatives.split('\n').forEach(a => refAlt[a[0]] = a.slice(2));
|
||||
mode = mode.toLowerCase();
|
||||
if (mode === "hard-unicode")
|
||||
convertor = (c) => `\\u${('000' + c.charCodeAt().toString(16)).slice(-4)}`;
|
||||
else if (mode === "soft-unicode")
|
||||
convertor = (c) => refAlt[c] || `\\u${('000' + c.charCodeAt().toString(16)).slice(-4)}`;
|
||||
else if (mode === "hard-remove")
|
||||
convertor = c => "";
|
||||
else if (mode === "soft-remove")
|
||||
convertor = c => refAlt[c] || "";
|
||||
else
|
||||
return null;
|
||||
for (let c in chars)
|
||||
result = result.replaceAll(c, convertor(c));
|
||||
return result;
|
||||
}
|
||||
|
||||
floCrypto.revertUnicode = function (string) {
|
||||
return string.replace(/\\u[\dA-F]{4}/gi,
|
||||
m => String.fromCharCode(parseInt(m.replace(/\\u/g, ''), 16)));
|
||||
}
|
||||
|
||||
})('object' === typeof module ? module.exports : window.floCrypto = {});
|
||||
File diff suppressed because one or more lines are too long
1
scripts/floTokenAPI.min.js
vendored
1
scripts/floTokenAPI.min.js
vendored
File diff suppressed because one or more lines are too long
9975
scripts/lib.js
9975
scripts/lib.js
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user