示例#1
0
        // NOTE when arg is an array, this method will corrupt the two registers adjacent to target_reg
        // "corrupt" in the sense of any value being there previousvly will be lost
        // this should be taken into account by methods that call this method
        // also this was not tested with nested arrays, might work, might not work yet
        private static void LoadIntoReg(ScriptBuilder sb, byte target_reg, object arg)
        {
            if (arg is string)
            {
                sb.EmitLoad(target_reg, (string)arg);
            }
            else
            if (arg is int)
            {
                sb.EmitLoad(target_reg, new BigInteger((int)arg));
            }
            else
            if (arg is long)
            {
                sb.EmitLoad(target_reg, new BigInteger((long)arg));
            }
            else
            if (arg is BigInteger)
            {
                sb.EmitLoad(target_reg, (BigInteger)arg);
            }
            else
            if (arg is bool)
            {
                sb.EmitLoad(target_reg, (bool)arg);
            }
            else
            if (arg is byte[])
            {
                sb.EmitLoad(target_reg, (byte[])arg, VMType.Bytes);
            }
            else
            if (arg is Enum)
            {
                sb.EmitLoad(target_reg, (Enum)arg);
            }
            else
            if (arg is Timestamp)
            {
                sb.EmitLoad(target_reg, (Timestamp)arg);
            }
            else
            if (arg is ISerializable)
            {
                sb.EmitLoad(target_reg, (ISerializable)arg);
            }
            else
            {
                var srcType = arg.GetType();

                if (srcType.IsArray)
                {
                    // this cast is required to clear any previous value that might be stored at target_reg
                    sb.Emit(Opcode.CAST, new byte[] { target_reg, target_reg, (byte)VMType.None });
                    var array = (Array)arg;
                    for (int j = 0; j < array.Length; j++)
                    {
                        var  element     = array.GetValue(j);
                        byte temp_regVal = (byte)(target_reg + 1);
                        byte temp_regKey = (byte)(target_reg + 2);
                        LoadIntoReg(sb, temp_regVal, element);
                        LoadIntoReg(sb, temp_regKey, j);
                        sb.Emit(Opcode.PUT, new byte[] { temp_regVal, target_reg, temp_regKey });
                    }
                }
                else
                {
                    throw new System.Exception("invalid type: " + srcType.Name);
                }
            }
        }
示例#2
0
 public static ScriptBuilder SpendGas(this ScriptBuilder sb, Address address)
 {
     CallContract(sb, "gas", "SpendGas", address);
     return(sb);
 }
示例#3
0
 public static ScriptBuilder AllowGas(this ScriptBuilder sb, Address from, Address to, BigInteger gasPrice, BigInteger gasLimit)
 {
     CallContract(sb, "gas", "AllowGas", from, to, gasPrice, gasLimit);
     return(sb);
 }
示例#4
0
 public static byte[] EndScript(this ScriptBuilder sb)
 {
     sb.Emit(VM.Opcode.RET);
     return(sb.ToScript());
 }
示例#5
0
        public static ScriptBuilder BeginScript()
        {
            var sb = new ScriptBuilder();

            return(sb);
        }
示例#6
0
        // returns register slot that contains the method name
        private static void InsertMethodArgs(ScriptBuilder sb, object[] args)
        {
            byte temp_reg = 0;

            for (int i = args.Length - 1; i >= 0; i--)
            {
                var arg = args[i];

                if (arg is string)
                {
                    sb.EmitLoad(temp_reg, (string)arg);
                    sb.EmitPush(temp_reg);
                }
                else
                if (arg is int)
                {
                    sb.EmitLoad(temp_reg, new BigInteger((int)arg));
                    sb.EmitPush(temp_reg);
                }
                else
                if (arg is BigInteger)
                {
                    sb.EmitLoad(temp_reg, (BigInteger)arg);
                    sb.EmitPush(temp_reg);
                }
                else
                if (arg is bool)
                {
                    sb.EmitLoad(temp_reg, (bool)arg);
                    sb.EmitPush(temp_reg);
                }
                else
                if (arg is byte[])
                {
                    sb.EmitLoad(temp_reg, (byte[])arg, VMType.Bytes);
                    sb.EmitPush(temp_reg);
                }
                else
                if (arg is Enum)
                {
                    sb.EmitLoad(temp_reg, (Enum)arg);
                    sb.EmitPush(temp_reg);
                }
                else
                if (arg is Address)
                {
                    sb.EmitLoad(temp_reg, ((Address)arg).PublicKey, VMType.Bytes);
                    sb.EmitPush(temp_reg);
                    sb.EmitExtCall("Address()", temp_reg);
                }
                else
                if (arg is Timestamp)
                {
                    sb.EmitLoad(temp_reg, ((Timestamp)arg).Value);
                    sb.EmitPush(temp_reg);
                    sb.EmitExtCall("Timestamp()", temp_reg);
                }
                else
                if (arg is Hash)
                {
                    sb.EmitLoad(temp_reg, ((Hash)arg).ToByteArray(), VMType.Bytes);
                    sb.EmitPush(temp_reg);
                    sb.EmitExtCall("Hash()", temp_reg);
                }
                else
                {
                    throw new System.Exception("invalid type");
                }
            }
        }