English
简体中文
繁体中文
Home
Blockchain
Wallet
Download
Developers
Documentation
Smart contracts
Developers forum
Q&A
Applications
Media & Contact
Sign In
Sign In
GitHub Login
Contract Name: Locker
Contract Description: Take Omega coins, lock it, and release on a preset schedule.
Author: omegasuite
Language: sc
Created: 2021-08-01 09:04:37
Version: 1.0
Status: created
Source Code
// this contract locks coins long _total; // total coins omega we have struct __outpoint__ _totalutxo; // the utxo for toal struct __outpoint__ _lastutxo; // the last omega coin utxo char [21]CONTRACT; // the current contract long _lockType; struct __outpoint__ _todestroy; struct __numcoinr__ _destroy; // define NET 0x6f void checkDestroy() { struct __storedata__ a; int op, i, ln; char [80]txo; char [80]buf; read(buf, abi("_destroy")); if (*(int*)buf != 0) { memcopy(&_destroy, buf + 4, *((int*)buf)); if (_destroy.value != 0) { read(buf, abi("_todestroy")); if (*(int*)buf != 0) { memcopy(&_todestroy, buf + 4, *((int*)buf)); addTxin(&_todestroy); _lockType = 0x4b434c02; // ascii for LCK with right memcopy(txo, (char*) &_lockType, 8); memcopy(txo + 8, (char*) &_destroy, 40); ln = 22; memcopy(txo + 48, (char *) &ln, 4); txo[52] = 0; txo[53] = 1; // 0x6f!!! txo[73] = 0x45; // OP_PAY2NONE addTxout(&op, txo); _destroy.value = 0; a.len = 40; a.data = (char*) &_destroy; write(abi("_destroy"), &a); delete(abi("_todestroy")); } } } } uchar zeroHash(uchar * h) { int i; uchar * p; i = 0; p = h; while (i < 32) { if ((*p) != 0) return 0; i += 1; p += 1; } return 1; } void setcontract() { char [30]buf; CONTRACT[0] = 0x88; getMeta(buf, "address"); memcopy(CONTRACT + 1, buf + 4, 20); } void sepndaccum(uchar tomerge, long txfees) { struct __storedata__ a; char [80]txo; int op; char [80]buf; read(buf, abi("_totalutxo")); if (*(int*)buf != 0) memcopy(&_totalutxo, buf + 4, *((int*)buf)); read(buf, abi("_lastutxo")); if (*(int*)buf != 0) { memcopy(&_lastutxo, buf + 4, *((int*)buf)); } addTxin(&_totalutxo); if (*(int*)buf != 0 && !zeroHash(_lastutxo.hash)) { addTxin(&_lastutxo); } if (tomerge) { // build txout _total -= txfees; maketxout(txo, 0, _total, nil, CONTRACT, 21); addTxout(&op, txo); getOutpoint(&_totalutxo); _totalutxo.index = op; } } void maketxout(char *txo, long tokentype, long amount, char * right, char *toaddress, int ln) { long wt; int wit; wt = tokentype; memcopy(txo, (char*) &wt, 8); wt = amount; memcopy(txo + 8, (char*) &wt, 8); wit = ln; if ((tokentype & 2) != 0) { memcopy(txo + 16, right, 32); memcopy(txo + 48, (char *) &wit, 4); memcopy(txo + 52, toaddress, 21); *(txo + 73) = 0x41; *(txo + 74) = 0; *(txo + 75) = 0; *(txo + 76) = 0; return; } memcopy(txo + 16, (char *) &wit, 4); memcopy(txo + 20, toaddress, 21); *(txo + 41) = 0x41; *(txo + 42) = 0; *(txo + 43) = 0; *(txo + 44) = 0; } struct trdef { char rtype; struct __RightDef__ rdef; }; void mintcoin(char *right, long amount, int firstIssue, int installs, int interval) { uchar [16]desc; struct __minttype__ minted; struct __coin__ issuing; uchar [128]src; struct __outpoint__ mintop; struct trdef tr; memcopy(desc, (uchar*)&firstIssue, 4); memcopy(desc + 4, (uchar*)&installs, 4); memcopy(desc + 8, (uchar*)&interval, 4); tr = {4,{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},12}}; tr.rdef.desc = desc; tr.rdef.attrib = 2; src[0] = 4; memcopy(src + 1, (uchar*) tr.rdef.father, 32); memcopy(src + 33, (uchar*) &tr.rdef.len, 4); memcopy(src + 37, desc, 12); src[49] = 2; addDefinition(right, src, 1); // 3 params for coinbase, 2 param for regular tx memcopy(issuing.data.numright.right, right, 32); // take mint type issuing.tokentype = _lockType; issuing.data.numright.value = amount; mint(&minted, &issuing); mintop = minted.minted; addTxin(&mintop); } public void deposit() { struct __storedata__ a; struct __coin__ c; char [80]buf; getCoin(&c); if (c.tokentype != 0 || c.data.num.value == 0) fail(); checkDestroy(); setcontract(); read(buf, abi("_total")); if (*(int*)buf != 8) _total = 0; else _total = *((long*)(buf + 4)); if (_total == 0) { _total = c.data.num.value; getOutpoint(&_totalutxo); } else { sepndaccum(1, 0); _total += c.data.num.value; getOutpoint(&_lastutxo); a.len = 36; a.data = (char*) &_lastutxo; write(abi("_lastutxo"), &a); } a.len = 8; a.data = (char*) &_total; write(abi("_total"), &a); a.len = 36; a.data = (char*) &_totalutxo; write(abi("_totalutxo"), &a); } public void lockcoins(char * toaddress, int firstIssue, int installs, int interval) { struct __storedata__ a; char [32]right; char vresult; int height; int now; long issued; char [80]txo; char [45]src; long isauable; struct __coin__ c; int op, i, ln; char [80]buf; getCoin(&c); if (c.tokentype != 0 || c.data.num.value == 0) fail(); checkDestroy(); setcontract(); _lockType = 0x4b434c02; // ascii for LOCK with right read(buf, abi("_total")); if (*(int*)buf != 8) _total = 0; else _total = *((long*)(buf + 4)); if (_total == 0) { _total = c.data.num.value; getOutpoint(&_totalutxo); } else if (_total > 2000) { sepndaccum(1, 2000); _total += c.data.num.value; getOutpoint(&_lastutxo); a.len = 36; a.data = (char*) &_lastutxo; write(abi("_lastutxo"), &a); } else { sepndaccum(0, 0); _total = c.data.num.value; getOutpoint(&_totalutxo); delete(abi("_lastutxo")); } a.len = 8; a.data = (char*) &_total; write(abi("_total"), &a); a.len = 36; a.data = (char*) &_totalutxo; write(abi("_totalutxo"), &a); mintcoin(right, c.data.num.value, firstIssue, installs, interval); // build a serialized txout maketxout(txo, _lockType, c.data.num.value, right, toaddress, 25); addTxout(&op, txo); } public void redeemcoins(char * toaddress) { // sig is signature on: 'invest' + '.issuecoins' + toaddress + amount + sequence struct __storedata__ a; char [32]right; char [32]h; char [50]src; char vresult; char [128]txo; int i, tm, op; struct __coin__ c; struct __definition__ def; int firstIssue, installs, interval; long amount, balance, txfees, j, tmt; char [128]buf; _lockType = 0x4b434c02; // 0x43494f4c02scii for LOCK with right getCoin(&c); if (c.tokentype != _lockType || c.data.numright.value == 0) { fail(); } checkDestroy(); setcontract(); // check right of input coin, is current block time greater than firstIssue? alloc(&def.data.right.desc, 16); getDefinition(buf, c.data.numright.right, 4); def.type = buf[0]; memcopy(def.data.right.father, buf + 1, 32); memcopy(&def.data.right.len, buf + 33, 4); memcopy(def.data.right.desc, buf + 37, def.data.right.len); j = 37 + (long) def.data.right.len; def.data.right.attrib = buf[j]; firstIssue = *((int*)def.data.right.desc); installs = *((int*)(def.data.right.desc + 4)); interval = *((int*)(def.data.right.desc + 8)); getBlockTime(&tm); if (tm < firstIssue || installs <= 0) fail(); // calculate redeemable amount: input amount / installs // new right: firstIssue = old firstIssue + interval, installs = old installs - 1 amount = 0; balance = c.data.numright.value; while (tm >= firstIssue && installs > 0) { if (installs == 1) { amount = c.data.numright.value; balance = 0; } else { tmt = balance / (long) installs; amount += tmt; balance -= tmt; } installs -= 1; firstIssue += interval; } maketxout(txo, 0, amount, nil, toaddress, 25); addTxout(&op, txo); // mint a new coin for input amount - redeemable omega coins with new right if (balance != 0) { mintcoin(right, balance, firstIssue, installs, interval); // build a serialized txout maketxout(txo, _lockType, balance, right, toaddress, 25); addTxout(&op, txo); } // add output for input amount - redeemable omega coins with new right read(buf, abi("_total")); if (*(int*)buf != 8) _total = 0; else _total = *((long*)(buf + 4)); // spend our omega coins sepndaccum(0, 2000); // add output for redeemable omega coins to address txfees = 2000; _total -= amount + txfees; if (_total <= 2000) _total = 0; if (_total > 0) { maketxout(txo, 0, _total, nil, CONTRACT, 21); addTxout(&op, txo); getOutpoint(&_totalutxo); _totalutxo.index = op; a.len = 36; a.data = (char*) &_totalutxo; write(abi("_totalutxo"), &a); } else delete(abi("_totalutxo")); delete(abi("_lastutxo")); a.len = 8; a.data = (char*) &_total; write(abi("_total"), &a); a.len = 40; a.data = (char*) &c.data.numright; write(abi("_destroy"), &a); getOutpoint(&_todestroy); a.data = (char*) &_todestroy; a.len = 36; write(abi("_todestroy"), &a); } void constructor() { struct __storedata__ a; int i; _total = 0; a.len = 8; a.data = (char*) &_total; write(abi("_total"), &a); a.len = 40; _destroy.value = 0; a.data = &_destroy; write(abi("_destroy"), &a); } public void _() { fail(); } public long total() { char [80]buf; read(buf, abi("_total")); if (*(int*)buf != 8) _total = 0; else _total = *((long*)(buf + 4)); output(8, (char*) &_total); return _total; } public struct __outpoint__ * totalutxo() { char [80]buf; read(buf, abi("_totalutxo")); if (*(int*)buf != 0) memcopy(&_totalutxo, buf + 4, *((int*)buf)); output(36, (char*) &_totalutxo); return _totalutxo; } public struct __outpoint__ * lastutxo() { char [80]buf; read(buf, abi("_lastutxo")); if (*(int*)buf != 0) memcopy(&_lastutxo, buf + 4, *((int*)buf)); output(36, (char*) &_lastutxo); return _lastutxo; } public struct __numcoinr__ * destroy() { char [80]buf; read(buf, abi("_destroy")); if (*(int*)buf != 0) memcopy(&_destroy, buf + 4, *((int*)buf)); output(40, (char*) &_destroy); return _destroy; } public struct __outpoint__ * todestroy() { char [80]buf; read(buf, abi("_todestroy")); if (*(int*)buf != 0) memcopy(&_todestroy, buf + 4, *((int*)buf)); output(36, (char*) &_todestroy); return _todestroy; }