示例#1
0
文件: segwit.go 项目: piotrnar/gocoin
func main() {
	var testnet bool
	if len(os.Args) != 2 {
		fmt.Println("Specify one P2KH bitcoin address to see it's P2SH-P2WPKH deposit address")
		fmt.Println("WARNING: Make sure the input address comes from an uncompressed key!!!!!")
		return
	}
	aa, er := btc.NewAddrFromString(os.Args[1])
	if er != nil {
		println(er.Error())
		return
	}

	if btc.AddrVerPubkey(false) == aa.Version {
	} else if btc.AddrVerPubkey(true) == aa.Version {
		testnet = true
	} else {
		fmt.Println("This does nto seem to be P2KH type address")
		return
	}

	h160 := btc.Rimp160AfterSha256(append([]byte{0, 20}, aa.Hash160[:]...))
	aa = btc.NewAddrFromHash160(h160[:], btc.AddrVerScript(testnet))
	fmt.Println(aa.String())
}
示例#2
0
func json_balance(w http.ResponseWriter, r *http.Request) {
	if !ipchecker(r) {
		return
	}

	if r.Method != "POST" {
		return
	}

	summary := len(r.Form["summary"]) > 0

	inp, er := ioutil.ReadAll(r.Body)
	if er != nil {
		println(er.Error())
		return
	}

	var addrs []string
	er = json.Unmarshal(inp, &addrs)
	if er != nil {
		println(er.Error())
		return
	}

	type OneOut struct {
		TxId     string
		Vout     uint32
		Value    uint64
		Height   uint32
		Coinbase bool
		Message  string
		Addr     string
	}

	type OneOuts struct {
		Value      uint64
		OutCnt     int
		SegWitCnt  int
		SegWitAddr string
		Outs       []OneOut
	}

	out := make(map[string]*OneOuts)

	lck := new(usif.OneLock)
	lck.In.Add(1)
	lck.Out.Add(1)
	usif.LocksChan <- lck
	lck.In.Wait()

	for _, a := range addrs {
		aa, e := btc.NewAddrFromString(a)
		if e != nil {
			continue
		}

		unsp := wallet.GetAllUnspent(aa)
		newrec := new(OneOuts)
		if len(unsp) > 0 {
			newrec.OutCnt = len(unsp)
			for _, u := range unsp {
				newrec.Value += u.Value
				if !summary {
					newrec.Outs = append(newrec.Outs, OneOut{
						TxId: btc.NewUint256(u.TxPrevOut.Hash[:]).String(), Vout: u.Vout,
						Value: u.Value, Height: u.MinedAt, Coinbase: u.Coinbase,
						Message: html.EscapeString(string(u.Message)), Addr: a})
				}
			}
		}
		out[aa.String()] = newrec

		/* Segwit P2WPKH: */
		if aa.Version == btc.AddrVerPubkey(common.Testnet) {
			// SegWit if applicable
			h160 := btc.Rimp160AfterSha256(append([]byte{0, 20}, aa.Hash160[:]...))
			aa = btc.NewAddrFromHash160(h160[:], btc.AddrVerScript(common.Testnet))
			newrec.SegWitAddr = aa.String()
			unsp = wallet.GetAllUnspent(aa)
			if len(unsp) > 0 {
				newrec.OutCnt += len(unsp)
				newrec.SegWitCnt = len(unsp)
				as := aa.String()
				for _, u := range unsp {
					newrec.Value += u.Value
					if !summary {
						newrec.Outs = append(newrec.Outs, OneOut{
							TxId: btc.NewUint256(u.TxPrevOut.Hash[:]).String(), Vout: u.Vout,
							Value: u.Value, Height: u.MinedAt, Coinbase: u.Coinbase,
							Message: html.EscapeString(string(u.Message)), Addr: as})
					}
				}
			}
		}
	}

	lck.Out.Done()

	bx, er := json.Marshal(out)
	if er == nil {
		w.Header()["Content-Type"] = []string{"application/json"}
		w.Write(bx)
	} else {
		println(er.Error())
	}
}
示例#3
0
文件: script.go 项目: liudch/gocoin
func evalScript(p []byte, stack *scrStack, tx *btc.Tx, inp int, ver_flags uint32) bool {
	if DBG_SCR {
		fmt.Println("script len", len(p))
	}

	if len(p) > 10000 {
		if DBG_ERR {
			fmt.Println("script too long", len(p))
		}
		return false
	}

	defer func() {
		if r := recover(); r != nil {
			if DBG_ERR {
				err, ok := r.(error)
				if !ok {
					err = fmt.Errorf("pkg: %v", r)
				}
				fmt.Println("evalScript panic:", err.Error())
				fmt.Println(string(debug.Stack()))
			}
		}
	}()

	var exestack scrStack
	var altstack scrStack
	sta, idx, opcnt := 0, 0, 0
	checkMinVals := (ver_flags & VER_MINDATA) != 0
	for idx < len(p) {
		inexec := exestack.nofalse()

		// Read instruction
		opcode, pushval, n, e := btc.GetOpcode(p[idx:])
		if e != nil {
			//fmt.Println(e.Error())
			//fmt.Println("A", idx, hex.EncodeToString(p))
			return false
		}
		idx += n

		if DBG_SCR {
			fmt.Printf("\nExecuting opcode 0x%02x  n=%d  inexec:%t  push:%s..\n",
				opcode, n, inexec, hex.EncodeToString(pushval))
			stack.print()
		}

		if pushval != nil && len(pushval) > btc.MAX_SCRIPT_ELEMENT_SIZE {
			if DBG_ERR {
				fmt.Println("pushval too long", len(pushval))
			}
			return false
		}

		if opcode > 0x60 {
			opcnt++
			if opcnt > 201 {
				if DBG_ERR {
					fmt.Println("evalScript: too many opcodes A")
				}
				return false
			}
		}

		if opcode == 0x7e /*OP_CAT*/ ||
			opcode == 0x7f /*OP_SUBSTR*/ ||
			opcode == 0x80 /*OP_LEFT*/ ||
			opcode == 0x81 /*OP_RIGHT*/ ||
			opcode == 0x83 /*OP_INVERT*/ ||
			opcode == 0x84 /*OP_AND*/ ||
			opcode == 0x85 /*OP_OR*/ ||
			opcode == 0x86 /*OP_XOR*/ ||
			opcode == 0x8d /*OP_2MUL*/ ||
			opcode == 0x8e /*OP_2DIV*/ ||
			opcode == 0x95 /*OP_MUL*/ ||
			opcode == 0x96 /*OP_DIV*/ ||
			opcode == 0x97 /*OP_MOD*/ ||
			opcode == 0x98 /*OP_LSHIFT*/ ||
			opcode == 0x99 /*OP_RSHIFT*/ {
			if DBG_ERR {
				fmt.Println("Unsupported opcode", opcode)
			}
			return false
		}

		if inexec && 0 <= opcode && opcode <= btc.OP_PUSHDATA4 {
			if checkMinVals && !checkMinimalPush(pushval, opcode) {
				if DBG_ERR {
					fmt.Println("Push value not in a minimal format", hex.EncodeToString(pushval))
				}
				return false
			}
			stack.push(pushval)
			if DBG_SCR {
				fmt.Println("pushed", len(pushval), "bytes")
			}
		} else if inexec || (0x63 /*OP_IF*/ <= opcode && opcode <= 0x68 /*OP_ENDIF*/) {
			switch {
			case opcode == 0x4f: // OP_1NEGATE
				stack.pushInt(-1)

			case opcode >= 0x51 && opcode <= 0x60: // OP_1-OP_16
				stack.pushInt(int64(opcode - 0x50))

			case opcode == 0x61: // OP_NOP
				// Do nothing

			/* - not handled
			OP_VER = 0x62
			*/

			case opcode == 0x63 || opcode == 0x64: //OP_IF || OP_NOTIF
				// <expression> if [statements] [else [statements]] endif
				val := false
				if inexec {
					if stack.size() < 1 {
						if DBG_ERR {
							fmt.Println("Stack too short for", opcode)
						}
						return false
					}
					if opcode == 0x63 /*OP_IF*/ {
						val = stack.popBool()
					} else {
						val = !stack.popBool()
					}
				}
				if DBG_SCR {
					fmt.Println(inexec, "if pushing", val, "...")
				}
				exestack.pushBool(val)

			/* - not handled
			   OP_VERIF = 0x65,
			   OP_VERNOTIF = 0x66,
			*/
			case opcode == 0x67: //OP_ELSE
				if exestack.size() == 0 {
					if DBG_ERR {
						fmt.Println("exestack empty in OP_ELSE")
					}
				}
				exestack.pushBool(!exestack.popBool())

			case opcode == 0x68: //OP_ENDIF
				if exestack.size() == 0 {
					if DBG_ERR {
						fmt.Println("exestack empty in OP_ENDIF")
					}
				}
				exestack.pop()

			case opcode == 0x69: //OP_VERIFY
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				if !stack.topBool(-1) {
					return false
				}
				stack.pop()

			case opcode == 0x6b: //OP_TOALTSTACK
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				altstack.push(stack.pop())

			case opcode == 0x6c: //OP_FROMALTSTACK
				if altstack.size() < 1 {
					if DBG_ERR {
						fmt.Println("AltStack too short for opcode", opcode)
					}
					return false
				}
				stack.push(altstack.pop())

			case opcode == 0x6d: //OP_2DROP
				if stack.size() < 2 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				stack.pop()
				stack.pop()

			case opcode == 0x6e: //OP_2DUP
				if stack.size() < 2 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				x1 := stack.top(-1)
				x2 := stack.top(-2)
				stack.push(x2)
				stack.push(x1)

			case opcode == 0x6f: //OP_3DUP
				if stack.size() < 3 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				x1 := stack.top(-3)
				x2 := stack.top(-2)
				x3 := stack.top(-1)
				stack.push(x1)
				stack.push(x2)
				stack.push(x3)

			case opcode == 0x70: //OP_2OVER
				if stack.size() < 4 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				x1 := stack.top(-4)
				x2 := stack.top(-3)
				stack.push(x1)
				stack.push(x2)

			case opcode == 0x71: //OP_2ROT
				// (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)
				if stack.size() < 6 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				x6 := stack.pop()
				x5 := stack.pop()
				x4 := stack.pop()
				x3 := stack.pop()
				x2 := stack.pop()
				x1 := stack.pop()
				stack.push(x3)
				stack.push(x4)
				stack.push(x5)
				stack.push(x6)
				stack.push(x1)
				stack.push(x2)

			case opcode == 0x72: //OP_2SWAP
				// (x1 x2 x3 x4 -- x3 x4 x1 x2)
				if stack.size() < 4 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				x4 := stack.pop()
				x3 := stack.pop()
				x2 := stack.pop()
				x1 := stack.pop()
				stack.push(x3)
				stack.push(x4)
				stack.push(x1)
				stack.push(x2)

			case opcode == 0x73: //OP_IFDUP
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				if stack.topBool(-1) {
					stack.push(stack.top(-1))
				}

			case opcode == 0x74: //OP_DEPTH
				stack.pushInt(int64(stack.size()))

			case opcode == 0x75: //OP_DROP
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				stack.pop()

			case opcode == 0x76: //OP_DUP
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				el := stack.pop()
				stack.push(el)
				stack.push(el)

			case opcode == 0x77: //OP_NIP
				if stack.size() < 2 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				x := stack.pop()
				stack.pop()
				stack.push(x)

			case opcode == 0x78: //OP_OVER
				if stack.size() < 2 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				stack.push(stack.top(-2))

			case opcode == 0x79 || opcode == 0x7a: //OP_PICK || OP_ROLL
				if stack.size() < 2 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				n := stack.popInt(checkMinVals)
				if n < 0 || n >= int64(stack.size()) {
					if DBG_ERR {
						fmt.Println("Wrong n for opcode", opcode)
					}
					return false
				}
				if opcode == 0x79 /*OP_PICK*/ {
					stack.push(stack.top(int(-1 - n)))
				} else if n > 0 {
					tmp := make([][]byte, n)
					for i := range tmp {
						tmp[i] = stack.pop()
					}
					xn := stack.pop()
					for i := len(tmp) - 1; i >= 0; i-- {
						stack.push(tmp[i])
					}
					stack.push(xn)
				}

			case opcode == 0x7b: //OP_ROT
				if stack.size() < 3 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				x3 := stack.pop()
				x2 := stack.pop()
				x1 := stack.pop()
				stack.push(x2)
				stack.push(x3)
				stack.push(x1)

			case opcode == 0x7c: //OP_SWAP
				if stack.size() < 2 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				x1 := stack.pop()
				x2 := stack.pop()
				stack.push(x1)
				stack.push(x2)

			case opcode == 0x7d: //OP_TUCK
				if stack.size() < 2 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				x1 := stack.pop()
				x2 := stack.pop()
				stack.push(x1)
				stack.push(x2)
				stack.push(x1)

			case opcode == 0x82: //OP_SIZE
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				stack.pushInt(int64(len(stack.top(-1))))

			case opcode == 0x87 || opcode == 0x88: //OP_EQUAL || OP_EQUALVERIFY
				if stack.size() < 2 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				a := stack.pop()
				b := stack.pop()
				if opcode == 0x88 { //OP_EQUALVERIFY
					if !bytes.Equal(a, b) {
						return false
					}
				} else {
					stack.pushBool(bytes.Equal(a, b))
				}

			/* - not handled
			OP_RESERVED1 = 0x89,
			OP_RESERVED2 = 0x8a,
			*/

			case opcode == 0x8b: //OP_1ADD
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				stack.pushInt(stack.popInt(checkMinVals) + 1)

			case opcode == 0x8c: //OP_1SUB
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				stack.pushInt(stack.popInt(checkMinVals) - 1)

			case opcode == 0x8f: //OP_NEGATE
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				stack.pushInt(-stack.popInt(checkMinVals))

			case opcode == 0x90: //OP_ABS
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				a := stack.popInt(checkMinVals)
				if a < 0 {
					stack.pushInt(-a)
				} else {
					stack.pushInt(a)
				}

			case opcode == 0x91: //OP_NOT
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				stack.pushBool(stack.popInt(checkMinVals) == 0)

			case opcode == 0x92: //OP_0NOTEQUAL
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				d := stack.pop()
				if checkMinVals && len(d) > 1 {
					if DBG_ERR {
						fmt.Println("Not minimal bool value", hex.EncodeToString(d))
					}
					return false
				}
				stack.pushBool(bts2bool(d))

			case opcode == 0x93 || //OP_ADD
				opcode == 0x94 || //OP_SUB
				opcode == 0x9a || //OP_BOOLAND
				opcode == 0x9b || //OP_BOOLOR
				opcode == 0x9c || opcode == 0x9d || //OP_NUMEQUAL || OP_NUMEQUALVERIFY
				opcode == 0x9e || //OP_NUMNOTEQUAL
				opcode == 0x9f || //OP_LESSTHAN
				opcode == 0xa0 || //OP_GREATERTHAN
				opcode == 0xa1 || //OP_LESSTHANOREQUAL
				opcode == 0xa2 || //OP_GREATERTHANOREQUAL
				opcode == 0xa3 || //OP_MIN
				opcode == 0xa4: //OP_MAX
				if stack.size() < 2 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				bn2 := stack.popInt(checkMinVals)
				bn1 := stack.popInt(checkMinVals)
				var bn int64
				switch opcode {
				case 0x93:
					bn = bn1 + bn2 // OP_ADD
				case 0x94:
					bn = bn1 - bn2 // OP_SUB
				case 0x9a:
					bn = b2i(bn1 != 0 && bn2 != 0) // OP_BOOLAND
				case 0x9b:
					bn = b2i(bn1 != 0 || bn2 != 0) // OP_BOOLOR
				case 0x9c:
					bn = b2i(bn1 == bn2) // OP_NUMEQUAL
				case 0x9d:
					bn = b2i(bn1 == bn2) // OP_NUMEQUALVERIFY
				case 0x9e:
					bn = b2i(bn1 != bn2) // OP_NUMNOTEQUAL
				case 0x9f:
					bn = b2i(bn1 < bn2) // OP_LESSTHAN
				case 0xa0:
					bn = b2i(bn1 > bn2) // OP_GREATERTHAN
				case 0xa1:
					bn = b2i(bn1 <= bn2) // OP_LESSTHANOREQUAL
				case 0xa2:
					bn = b2i(bn1 >= bn2) // OP_GREATERTHANOREQUAL
				case 0xa3: // OP_MIN
					if bn1 < bn2 {
						bn = bn1
					} else {
						bn = bn2
					}
				case 0xa4: // OP_MAX
					if bn1 > bn2 {
						bn = bn1
					} else {
						bn = bn2
					}
				default:
					panic("invalid opcode")
				}
				if opcode == 0x9d { //OP_NUMEQUALVERIFY
					if bn == 0 {
						return false
					}
				} else {
					stack.pushInt(bn)
				}

			case opcode == 0xa5: //OP_WITHIN
				if stack.size() < 3 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				bn3 := stack.popInt(checkMinVals)
				bn2 := stack.popInt(checkMinVals)
				bn1 := stack.popInt(checkMinVals)
				stack.pushBool(bn2 <= bn1 && bn1 < bn3)

			case opcode == 0xa6: //OP_RIPEMD160
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				rim := ripemd160.New()
				rim.Write(stack.pop()[:])
				stack.push(rim.Sum(nil)[:])

			case opcode == 0xa7: //OP_SHA1
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				sha := sha1.New()
				sha.Write(stack.pop()[:])
				stack.push(sha.Sum(nil)[:])

			case opcode == 0xa8: //OP_SHA256
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				sha := sha256.New()
				sha.Write(stack.pop()[:])
				stack.push(sha.Sum(nil)[:])

			case opcode == 0xa9: //OP_HASH160
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				rim160 := btc.Rimp160AfterSha256(stack.pop())
				stack.push(rim160[:])

			case opcode == 0xaa: //OP_HASH256
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				h := btc.Sha2Sum(stack.pop())
				stack.push(h[:])

			case opcode == 0xab: // OP_CODESEPARATOR
				sta = idx

			case opcode == 0xac || opcode == 0xad: // OP_CHECKSIG || OP_CHECKSIGVERIFY

				if stack.size() < 2 {
					if DBG_ERR {
						fmt.Println("Stack too short for opcode", opcode)
					}
					return false
				}
				var ok bool
				pk := stack.pop()
				si := stack.pop()

				// BIP-0066
				if !CheckSignatureEncoding(si, ver_flags) {
					if DBG_ERR {
						fmt.Println("Invalid Signature Encoding A")
					}
					return false
				}

				if len(si) > 0 {
					sh := tx.SignatureHash(delSig(p[sta:], si), inp, int32(si[len(si)-1]))
					ok = btc.EcdsaVerify(pk, si, sh)
				}
				if !ok && DBG_ERR {
					if DBG_ERR {
						fmt.Println("EcdsaVerify fail 1")
					}
				}

				if DBG_SCR {
					fmt.Println("ver:", ok)
				}
				if opcode == 0xad {
					if !ok { // OP_CHECKSIGVERIFY
						return false
					}
				} else { // OP_CHECKSIG
					stack.pushBool(ok)
				}

			case opcode == 0xae || opcode == 0xaf: //OP_CHECKMULTISIG || OP_CHECKMULTISIGVERIFY
				//fmt.Println("OP_CHECKMULTISIG ...")
				//stack.print()
				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("OP_CHECKMULTISIG: Stack too short A")
					}
					return false
				}
				i := 1
				keyscnt := stack.topInt(-i, checkMinVals)
				if keyscnt < 0 || keyscnt > 20 {
					fmt.Println("OP_CHECKMULTISIG: Wrong number of keys")
					return false
				}
				opcnt += int(keyscnt)
				if opcnt > 201 {
					if DBG_ERR {
						fmt.Println("evalScript: too many opcodes B")
					}
					return false
				}
				i++
				ikey := i
				i += int(keyscnt)
				if stack.size() < i {
					if DBG_ERR {
						fmt.Println("OP_CHECKMULTISIG: Stack too short B")
					}
					return false
				}
				sigscnt := stack.topInt(-i, checkMinVals)
				if sigscnt < 0 || sigscnt > keyscnt {
					fmt.Println("OP_CHECKMULTISIG: sigscnt error")
					return false
				}
				i++
				isig := i
				i += int(sigscnt)
				if stack.size() < i {
					if DBG_ERR {
						fmt.Println("OP_CHECKMULTISIG: Stack too short C")
					}
					return false
				}

				xxx := p[sta:]
				for k := 0; k < int(sigscnt); k++ {
					xxx = delSig(xxx, stack.top(-isig-k))
				}

				success := true
				for sigscnt > 0 {
					pk := stack.top(-ikey)
					si := stack.top(-isig)

					// BIP-0066
					if !CheckSignatureEncoding(si, ver_flags) {
						if DBG_ERR {
							fmt.Println("Invalid Signature Encoding B")
						}
						return false
					}

					if len(si) > 0 {
						sh := tx.SignatureHash(xxx, inp, int32(si[len(si)-1]))
						if btc.EcdsaVerify(pk, si, sh) {
							isig++
							sigscnt--
						}
					}

					ikey++
					keyscnt--

					// If there are more signatures left than keys left,
					// then too many signatures have failed
					if sigscnt > keyscnt {
						success = false
						break
					}
				}
				for i > 0 {
					i--
					stack.pop()
				}
				if opcode == 0xaf {
					if !success { // OP_CHECKMULTISIGVERIFY
						return false
					}
				} else {
					stack.pushBool(success)
				}

			case opcode >= 0xb1: //OP_NOP2 or OP_CHECKLOCKTIMEVERIFY
				if DBG_SCR {
					println("OP_NOP2...")
				}

				if (ver_flags & VER_CLTV) == 0 {
					break // Just do NOP2
				}

				if DBG_SCR {
					println("OP_CHECKLOCKTIMEVERIFY...")
				}

				if stack.size() < 1 {
					if DBG_ERR {
						fmt.Println("OP_CHECKLOCKTIMEVERIFY: Stack too short")
					}
					return false
				}

				d := stack.top(-1)
				if len(d) > 5 {
					if DBG_ERR {
						fmt.Println("OP_CHECKLOCKTIMEVERIFY: locktime field too long", len(d))
					}
					return false
				}

				if DBG_SCR {
					fmt.Println("val from stack", hex.EncodeToString(d))
				}

				locktime := bts2int_ext(d, 5, checkMinVals)
				if locktime < 0 {
					if DBG_ERR {
						fmt.Println("OP_CHECKLOCKTIMEVERIFY: negative locktime")
					}
					return false
				}

				if !((tx.Lock_time < LOCKTIME_THRESHOLD && locktime < LOCKTIME_THRESHOLD) ||
					(tx.Lock_time >= LOCKTIME_THRESHOLD && locktime >= LOCKTIME_THRESHOLD)) {
					if DBG_ERR {
						fmt.Println("OP_CHECKLOCKTIMEVERIFY: broken lock value")
					}
					return false
				}

				if DBG_SCR {
					println("locktime > int64(tx.Lock_time)", locktime, int64(tx.Lock_time))
					println(" ... seq", len(tx.TxIn), inp, tx.TxIn[inp].Sequence)
				}

				// Actually compare the specified lock time with the transaction.
				if locktime > int64(tx.Lock_time) {
					if DBG_ERR {
						fmt.Println("OP_CHECKLOCKTIMEVERIFY: Locktime requirement not satisfied")
					}
					return false
				}

				if tx.TxIn[inp].Sequence == 0xffffffff {
					if DBG_ERR {
						fmt.Println("OP_CHECKLOCKTIMEVERIFY: TxIn final")
					}
					return false
				}

				// OP_CHECKLOCKTIMEVERIFY passed successfully

			case opcode >= 0xb0 || opcode >= 0xb2 && opcode <= 0xb9: //OP_NOP1 || OP_NOP3..OP_NOP10
				// just do nothing

			default:
				if DBG_ERR {
					fmt.Printf("Unhandled opcode 0x%02x - a handler must be implemented\n", opcode)
					stack.print()
					fmt.Println("Rest of the script:", hex.EncodeToString(p[idx:]))
				}
				return false
			}
		}

		if DBG_SCR {
			fmt.Printf("Finished Executing opcode 0x%02x\n", opcode)
			stack.print()
		}
		if stack.size()+altstack.size() > 1000 {
			if DBG_ERR {
				fmt.Println("Stack too big")
			}
			return false
		}
	}

	if DBG_SCR {
		fmt.Println("END OF SCRIPT")
		stack.print()
	}

	if exestack.size() > 0 {
		if DBG_ERR {
			fmt.Println("Unfinished if..")
		}
		return false
	}

	return true
}
示例#4
0
func dl_balance(w http.ResponseWriter, r *http.Request) {
	if !ipchecker(r) {
		return
	}

	if r.Method != "POST" {
		return
	}

	var addrs []string
	var labels []string

	if len(r.Form["addrcnt"]) != 1 {
		println("no addrcnt")
		return
	}
	addrcnt, _ := strconv.ParseUint(r.Form["addrcnt"][0], 10, 32)

	for i := 0; i < int(addrcnt); i++ {
		is := fmt.Sprint(i)
		if len(r.Form["addr"+is]) == 1 {
			addrs = append(addrs, r.Form["addr"+is][0])
			if len(r.Form["label"+is]) == 1 {
				labels = append(labels, r.Form["label"+is][0])
			} else {
				labels = append(labels, "")
			}
		}
	}

	type one_unsp_rec struct {
		btc.TxPrevOut
		Value    uint64
		Addr     string
		MinedAt  uint32
		Coinbase bool
	}

	var thisbal chain.AllUnspentTx

	lck := new(usif.OneLock)
	lck.In.Add(1)
	lck.Out.Add(1)
	usif.LocksChan <- lck
	lck.In.Wait()

	for idx, a := range addrs {
		aa, e := btc.NewAddrFromString(a)
		aa.Extra.Label = labels[idx]
		if e == nil {
			newrecs := wallet.GetAllUnspent(aa)
			if len(newrecs) > 0 {
				thisbal = append(thisbal, newrecs...)
			}

			/* Segwit P2WPKH: */
			if aa.Version == btc.AddrVerPubkey(common.Testnet) {
				// SegWit if applicable
				h160 := btc.Rimp160AfterSha256(append([]byte{0, 20}, aa.Hash160[:]...))
				aa = btc.NewAddrFromHash160(h160[:], btc.AddrVerScript(common.Testnet))
				newrecs = wallet.GetAllUnspent(aa)
				if len(newrecs) > 0 {
					thisbal = append(thisbal, newrecs...)
				}
			}
		}
	}
	lck.Out.Done()

	buf := new(bytes.Buffer)
	zi := zip.NewWriter(buf)
	was_tx := make(map[[32]byte]bool)

	sort.Sort(thisbal)
	for i := range thisbal {
		if was_tx[thisbal[i].TxPrevOut.Hash] {
			continue
		}
		was_tx[thisbal[i].TxPrevOut.Hash] = true
		txid := btc.NewUint256(thisbal[i].TxPrevOut.Hash[:])
		fz, _ := zi.Create("balance/" + txid.String() + ".tx")
		if dat, er := common.BlockChain.GetRawTx(thisbal[i].MinedAt, txid); er == nil {
			fz.Write(dat)
		} else {
			println(er.Error())
		}
	}

	fz, _ := zi.Create("balance/unspent.txt")
	for i := range thisbal {
		fmt.Fprintln(fz, thisbal[i].UnspentTextLine())
	}

	zi.Close()
	w.Header()["Content-Type"] = []string{"application/zip"}
	w.Write(buf.Bytes())

}
示例#5
0
文件: wallet.go 项目: piotrnar/gocoin
// Get the secret seed and generate "keycnt" key pairs (both private and public)
func make_wallet() {
	var lab string

	load_others()

	var seed_key []byte
	var hdwal *btc.HDWallet

	defer func() {
		sys.ClearBuffer(seed_key)
		if hdwal != nil {
			sys.ClearBuffer(hdwal.Key)
			sys.ClearBuffer(hdwal.ChCode)
		}
	}()

	pass := getpass()
	if pass == nil {
		cleanExit(0)
	}

	if waltype >= 1 && waltype <= 3 {
		seed_key = make([]byte, 32)
		btc.ShaHash(pass, seed_key)
		sys.ClearBuffer(pass)
		lab = fmt.Sprintf("Typ%c", 'A'+waltype-1)
		if waltype == 1 {
			println("WARNING: Wallet Type 1 is obsolete")
		} else if waltype == 2 {
			if type2sec != "" {
				d, e := hex.DecodeString(type2sec)
				if e != nil {
					println("t2sec error:", e.Error())
					cleanExit(1)
				}
				type2_secret = d
			} else {
				type2_secret = make([]byte, 20)
				btc.RimpHash(seed_key, type2_secret)
			}
		}
	} else if waltype == 4 {
		lab = "TypHD"
		hdwal = btc.MasterKey(pass, testnet)
		sys.ClearBuffer(pass)
	} else {
		sys.ClearBuffer(pass)
		println("ERROR: Unsupported wallet type", waltype)
		cleanExit(1)
	}

	if *verbose {
		fmt.Println("Generating", keycnt, "keys, version", ver_pubkey(), "...")
	}

	first_determ_idx = len(keys)
	for i := uint(0); i < keycnt; {
		prv_key := make([]byte, 32)
		if waltype == 3 {
			btc.ShaHash(seed_key, prv_key)
			seed_key = append(seed_key, byte(i))
		} else if waltype == 2 {
			seed_key = btc.DeriveNextPrivate(seed_key, type2_secret)
			copy(prv_key, seed_key)
		} else if waltype == 1 {
			btc.ShaHash(seed_key, prv_key)
			copy(seed_key, prv_key)
		} else /*if waltype==4*/ {
			// HD wallet
			_hd := hdwal.Child(uint32(0x80000000 | i))
			copy(prv_key, _hd.Key[1:])
			sys.ClearBuffer(_hd.Key)
			sys.ClearBuffer(_hd.ChCode)
		}
		if *scankey != "" {
			new_stealth_address(prv_key)
			return
		}

		rec := btc.NewPrivateAddr(prv_key, ver_secret(), !uncompressed)

		if *pubkey != "" && *pubkey == rec.BtcAddr.String() {
			fmt.Println("Public address:", rec.BtcAddr.String())
			fmt.Println("Public hexdump:", hex.EncodeToString(rec.BtcAddr.Pubkey))
			return
		}

		rec.BtcAddr.Extra.Label = fmt.Sprint(lab, " ", i+1)
		keys = append(keys, rec)
		i++
	}
	if *verbose {
		fmt.Println("Private keys re-generated")
	}

	// Calculate SegWit addresses
	segwit = make([]*btc.BtcAddr, len(keys))
	for i, pk := range keys {
		if len(pk.Pubkey) != 33 {
			continue
		}
		h160 := btc.Rimp160AfterSha256(append([]byte{0, 20}, pk.Hash160[:]...))
		segwit[i] = btc.NewAddrFromHash160(h160[:], btc.AddrVerScript(testnet))
	}
}