Qortal UI - Main Code Repository A User Interface for the Qortal Blockchain Project. Truly decentralized web hosting, application hosting, communications, data storage, and full infrastructure for the future global decentralized digital world.
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

3 years ago
// 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;
}