mirror of https://github.com/qortal/qortal-ui
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
336 lines
10 KiB
336 lines
10 KiB
// QORA |
|
|
|
const TYPES = { |
|
GENESIS_TRANSACTION: 1, |
|
PAYMENT_TRANSACTION: 2, |
|
|
|
REGISTER_NAME_TRANSACTION: 3, |
|
UPDATE_NAME_TRANSACTION: 4, |
|
SELL_NAME_TRANSACTION: 5, |
|
CANCEL_SELL_NAME_TRANSACTION: 6, |
|
BUY_NAME_TRANSACTION: 7, |
|
|
|
CREATE_POLL_TRANSACTION: 8, |
|
VOTE_ON_POLL_TRANSACTION: 9, |
|
|
|
ARBITRARY_TRANSACTION: 10, |
|
|
|
ISSUE_ASSET_TRANSACTION: 11, |
|
TRANSFER_ASSET_TRANSACTION: 12, |
|
CREATE_ORDER_TRANSACTION: 13, |
|
CANCEL_ORDER_TRANSACTION: 14, |
|
MULTI_PAYMENT_TRANSACTION: 15, |
|
|
|
DEPLOY_AT_TRANSACTION: 16, |
|
|
|
MESSAGE_TRANSACTION: 17 |
|
}; |
|
|
|
function getKeyPairFromSeed(seed, returnBase58) |
|
{ |
|
if(typeof(seed) == "string") { |
|
seed = new Uint8Array(Base58.decode(seed)); |
|
} |
|
|
|
var keyPair = nacl.sign.keyPair.fromSeed(seed); |
|
|
|
var base58privateKey = Base58.encode(keyPair.secretKey); |
|
var base58publicKey = Base58.encode(keyPair.publicKey); |
|
if(returnBase58) { |
|
return { |
|
privateKey: Base58.encode(keyPair.secretKey), |
|
publicKey: Base58.encode(keyPair.publicKey) |
|
}; |
|
} else { |
|
return { |
|
privateKey: keyPair.secretKey, |
|
publicKey: keyPair.publicKey |
|
}; |
|
} |
|
} |
|
|
|
function stringtoUTF8Array(message) { |
|
if (typeof message == 'string') { |
|
var s = unescape(encodeURIComponent(message)); // UTF-8 |
|
message = new Uint8Array(s.length); |
|
for (var i = 0; i < s.length; i++) { |
|
message[i] = s.charCodeAt(i) & 0xff; |
|
} |
|
} |
|
return message; |
|
} |
|
|
|
function int32ToBytes (word) { |
|
var byteArray = []; |
|
for (var b = 0; b < 32; b += 8) { |
|
byteArray.push((word >>> (24 - b % 32)) & 0xFF); |
|
} |
|
return byteArray; |
|
} |
|
|
|
function int64ToBytes (int64) { |
|
// we want to represent the input as a 8-bytes array |
|
var byteArray = [0, 0, 0, 0, 0, 0, 0, 0]; |
|
|
|
for ( var index = 0; index < byteArray.length; index ++ ) { |
|
var byte = int64 & 0xff; |
|
byteArray [ byteArray.length - index - 1 ] = byte; |
|
int64 = (int64 - byte) / 256 ; |
|
} |
|
|
|
return byteArray; |
|
} |
|
|
|
function appendBuffer (buffer1, buffer2) { |
|
buffer1 = new Uint8Array(buffer1); |
|
buffer2 = new Uint8Array(buffer2); |
|
var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength); |
|
tmp.set(buffer1, 0); |
|
tmp.set(buffer2, buffer1.byteLength); |
|
return tmp; |
|
} |
|
|
|
function equal (buf1, buf2) |
|
{ |
|
if (buf1.byteLength != buf2.byteLength) return false; |
|
var dv1 = new Uint8Array(buf1); |
|
var dv2 = new Uint8Array(buf2); |
|
for (var i = 0; i != buf1.byteLength; i++) |
|
{ |
|
if (dv1[i] != dv2[i]) return false; |
|
} |
|
return true; |
|
} |
|
|
|
function generateAccountSeed(seed, nonce, returnBase58) |
|
{ |
|
if(typeof(seed) == "string") { |
|
seed = Base58.decode(seed); |
|
} |
|
|
|
nonceBytes = int32ToBytes(nonce); |
|
|
|
var resultSeed = new Uint8Array(); |
|
|
|
resultSeed = appendBuffer(resultSeed, nonceBytes); |
|
resultSeed = appendBuffer(resultSeed, seed); |
|
resultSeed = appendBuffer(resultSeed, nonceBytes); |
|
|
|
if(returnBase58) { |
|
return Base58.encode(SHA256.digest(SHA256.digest(resultSeed))); |
|
} else { |
|
return new SHA256.digest(SHA256.digest(resultSeed)); |
|
} |
|
|
|
} |
|
|
|
function getAccountAddressFromPublicKey(publicKey) |
|
{ |
|
var ADDRESS_VERSION = 58; // Q |
|
|
|
if(typeof(publicKey) == "string") { |
|
publicKey = Base58.decode(publicKey); |
|
} |
|
|
|
var publicKeyHashSHA256 = SHA256.digest(publicKey); |
|
|
|
var ripemd160 = new RIPEMD160(); |
|
|
|
var publicKeyHash = ripemd160.digest(publicKeyHashSHA256); |
|
|
|
var addressArray = new Uint8Array(); |
|
|
|
addressArray = appendBuffer(addressArray, [ADDRESS_VERSION]); |
|
addressArray = appendBuffer(addressArray, publicKeyHash); |
|
|
|
var checkSum = SHA256.digest(SHA256.digest(addressArray)); |
|
|
|
addressArray = appendBuffer(addressArray, checkSum.subarray(0, 4)); |
|
|
|
return Base58.encode(addressArray); |
|
} |
|
|
|
function getAccountAddressType(address) |
|
{ |
|
try { |
|
var ADDRESS_VERSION = 58; // Q |
|
var AT_ADDRESS_VERSION = 23; // A |
|
|
|
if(typeof(address) == "string") { |
|
address = Base58.decode(address); |
|
} |
|
|
|
var checkSum = address.subarray(address.length - 4, address.length) |
|
var addressWitoutChecksum = address.subarray(0, address.length - 4); |
|
|
|
var checkSumTwo = SHA256.digest(SHA256.digest(addressWitoutChecksum)); |
|
checkSumTwo = checkSumTwo.subarray(0, 4); |
|
|
|
if (equal(checkSum, checkSumTwo)) |
|
{ |
|
if(address[0] == ADDRESS_VERSION) |
|
{ |
|
return "standard"; |
|
} |
|
if(address[0] == AT_ADDRESS_VERSION) |
|
{ |
|
return "at"; |
|
} |
|
} |
|
|
|
return "invalid"; |
|
|
|
} catch (e) { |
|
return "invalid"; |
|
} |
|
} |
|
|
|
function isValidAddress(address) |
|
{ |
|
return (getAccountAddressType(address) != "invalid"); |
|
} |
|
|
|
function generateSignaturePaymentTransaction(keyPair, lastReference, recipient, amount, fee, timestamp) { |
|
const data = generatePaymentTransactionBase(keyPair.publicKey, lastReference, recipient, amount, fee, timestamp); |
|
return nacl.sign.detached(data, keyPair.privateKey); |
|
} |
|
|
|
function generatePaymentTransaction(keyPair, lastReference, recipient, amount, fee, timestamp, signature) { |
|
return appendBuffer(generatePaymentTransactionBase(keyPair.publicKey, lastReference, recipient, amount, fee, timestamp), |
|
signature); |
|
} |
|
|
|
function generatePaymentTransactionBase(publicKey, lastReference, recipient, amount, fee, timestamp) { |
|
const txType = TYPES.PAYMENT_TRANSACTION; |
|
const typeBytes = int32ToBytes(txType); |
|
const timestampBytes = int64ToBytes(timestamp); |
|
const amountBytes = int64ToBytes(amount * 100000000); |
|
const feeBytes = int64ToBytes(fee * 100000000); |
|
|
|
var data = new Uint8Array(); |
|
|
|
data = appendBuffer(data, typeBytes); |
|
data = appendBuffer(data, timestampBytes); |
|
data = appendBuffer(data, lastReference); |
|
data = appendBuffer(data, publicKey); |
|
data = appendBuffer(data, recipient); |
|
data = appendBuffer(data, amountBytes); |
|
data = appendBuffer(data, feeBytes); |
|
|
|
return data; |
|
} |
|
|
|
function generateSignatureMessageTransaction(keyPair, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted) { |
|
const data = generateMessageTransactionBase(keyPair.publicKey, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted); |
|
return nacl.sign.detached(data, keyPair.privateKey); |
|
} |
|
|
|
function generateMessageTransaction(keyPair, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted, signature) { |
|
return appendBuffer(generateMessageTransactionBase(keyPair.publicKey, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted), |
|
signature); |
|
} |
|
|
|
function generateMessageTransactionBase(publicKey, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted) { |
|
txType = TYPES.MESSAGE_TRANSACTION; |
|
|
|
const typeBytes = int32ToBytes(txType); |
|
const timestampBytes = int64ToBytes(timestamp); |
|
const amountBytes = int64ToBytes(amount * 100000000); |
|
const feeBytes = int64ToBytes(fee * 100000000); |
|
const messageLength = int32ToBytes(message.length); |
|
const key = int64ToBytes(0); |
|
|
|
isTextB = new Uint8Array(1); |
|
isTextB[0] = isText; |
|
|
|
isEncryptedB = new Uint8Array(1); |
|
isEncryptedB[0] = isEncrypted; |
|
|
|
var data = new Uint8Array(); |
|
|
|
data = appendBuffer(data, typeBytes); |
|
data = appendBuffer(data, timestampBytes); |
|
data = appendBuffer(data, lastReference); |
|
data = appendBuffer(data, publicKey); |
|
data = appendBuffer(data, recipient); |
|
data = appendBuffer(data, key); |
|
data = appendBuffer(data, amountBytes); |
|
data = appendBuffer(data, messageLength); |
|
data = appendBuffer(data, message); |
|
data = appendBuffer(data, isEncryptedB); |
|
data = appendBuffer(data, isTextB); |
|
data = appendBuffer(data, feeBytes); |
|
|
|
return data; |
|
} |
|
|
|
|
|
function generateSignatureArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp) { |
|
const data = generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp); |
|
return nacl.sign.detached(data, keyPair.privateKey); |
|
} |
|
|
|
function generateArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp, signature) { |
|
return appendBuffer(generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp), |
|
signature); |
|
} |
|
|
|
function generateArbitraryTransactionV3Base(publicKey, lastReference, service, arbitraryData, fee, timestamp) { |
|
const txType = TYPES.ARBITRARY_TRANSACTION; |
|
const typeBytes = int32ToBytes(txType); |
|
const timestampBytes = int64ToBytes(timestamp); |
|
const feeBytes = int64ToBytes(fee * 100000000); |
|
const serviceBytes = int32ToBytes(service); |
|
const dataSizeBytes = int32ToBytes(arbitraryData.length); |
|
const paymentsLengthBytes = int32ToBytes(0); // Support payments - not yet. |
|
|
|
var data = new Uint8Array(); |
|
|
|
data = appendBuffer(data, typeBytes); |
|
data = appendBuffer(data, timestampBytes); |
|
data = appendBuffer(data, lastReference); |
|
data = appendBuffer(data, publicKey); |
|
data = appendBuffer(data, paymentsLengthBytes); |
|
// Here it is necessary to insert the payments, if there are |
|
data = appendBuffer(data, serviceBytes); |
|
data = appendBuffer(data, dataSizeBytes); |
|
data = appendBuffer(data, arbitraryData); |
|
data = appendBuffer(data, feeBytes); |
|
|
|
return data; |
|
} |
|
|
|
|
|
function generateSignatureRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp) { |
|
const data = generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp); |
|
return nacl.sign.detached(data, keyPair.privateKey); |
|
} |
|
|
|
function generateRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp, signature) { |
|
return appendBuffer( generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp), |
|
signature ); |
|
} |
|
|
|
function generateRegisterNameTransactionBase(publicKey, lastReference, owner, name, value, fee, timestamp) { |
|
const txType = TYPES.REGISTER_NAME_TRANSACTION; |
|
const typeBytes = int32ToBytes(txType); |
|
const timestampBytes = int64ToBytes(timestamp); |
|
const feeBytes = int64ToBytes(fee * 100000000); |
|
const nameSizeBytes = int32ToBytes(name.length); |
|
const valueSizeBytes = int32ToBytes(value.length); |
|
|
|
var data = new Uint8Array(); |
|
|
|
data = appendBuffer(data, typeBytes); |
|
data = appendBuffer(data, timestampBytes); |
|
data = appendBuffer(data, lastReference); |
|
data = appendBuffer(data, publicKey); |
|
data = appendBuffer(data, owner); |
|
data = appendBuffer(data, nameSizeBytes); |
|
data = appendBuffer(data, name); |
|
data = appendBuffer(data, valueSizeBytes); |
|
data = appendBuffer(data, value); |
|
data = appendBuffer(data, feeBytes); |
|
|
|
return data; |
|
} |