import { Address , Blockchain , constant , Deploy , Fixed , Hash256 , Integer , LinkedSmartContract , receive , SmartContract , } from '@neo-one/smart-contract' ; import { Coin } from './Coin' ; export class CoinICO extends SmartContract { public readonly properties = { codeVersion : '1.0' , author : 'dicarlo2' , email : 'alex.dicarlo@neotracker.io' , description : 'NEO•ONE Coin ICO' , } ; public readonly amountPerNEO = 10 ; private mutableRemaining : Fixed < 8 > = 1000000000000000 ; public constructor ( public readonly owner = Deploy . senderAddress , public readonly startTimeSeconds = Blockchain . currentBlockTime , public readonly icoDurationSeconds = 157700000 ) { super ( ) ; if ( ! Address . isCaller ( owner ) ) { throw new Error ( 'Sender was not the owner.' ) ; } } @ constant public get remaining ( ) : Fixed < 8 > { return this . mutableRemaining ; } @ receive public mintTokens ( ) { if ( ! this . hasStarted ( ) || this . hasEnded ( ) ) { throw new Error ( 'Invalid mintTokens' ) ; } const { references } = Blockchain . currentTransaction ; if ( references . length === 0 ) { throw new Error ( 'Invalid mintTokens' ) ; } const sender = references [ 0 ] . address ; let amount = 0 ; for ( const output of Blockchain . currentTransaction . outputs ) { if ( output . address . equals ( this . address ) ) { if ( ! output . asset . equals ( Hash256 . NEO ) ) { throw new Error ( 'Invalid mintTokens' ) ; } amount += output . value * this . amountPerNEO ; } } if ( amount > this . remaining ) { throw new Error ( 'Invalid mintTokens' ) ; } if ( amount === 0 ) { throw new Error ( 'Invalid mintTokens' ) ; } const coin = LinkedSmartContract . for < Coin > ( ) ; if ( ! coin . issue ( sender , amount ) ) { throw new Error ( 'Invalid mintTokens' ) ; } this . mutableRemaining -= amount ; } private hasStarted ( ) { return Blockchain . currentBlockTime >= this . startTimeSeconds ; } private hasEnded ( ) { return Blockchain . currentBlockTime > this . startTimeSeconds + this . icoDurationSeconds ; } }