<p>The value that is hashed is the single byte <code>0x94</code>.</p>

<p>The stack contains vectors of unsigned chars. OP_NEGATE converts the int <code>-20</code> into a vector of unsigned chars by calling <code>CScriptNum::getvch()</code> <a href="https://github.com/bitcoin/bitcoin/blob/v0.10.1/src/script/interpreter.cpp#L671" rel="nofollow">here</a>:</p>

<pre><code>stack.push_back(bn.getvch());
</code></pre>

<p><code>CScriptNum::getvch()</code> <a href="https://github.com/bitcoin/bitcoin/blob/v0.10.1/src/script/script.h#L282-L318" rel="nofollow">serializes ints into bytes</a> by taking its absolute value, encoding the result in <a href="https://en.wikipedia.org/wiki/Endianness" rel="nofollow">little-endian</a> form using the fewest number of bytes possible, and then guarantying that the most significant bit of the most significant byte is set if and only if the value is negative.</p>

<p>Therefore <code>-20</code> is serialized into the single byte <code>0x80 + 20 == 0x94</code>.</p>

<p>This can be further verified by completing the rest of the script:</p>

<pre><code>$ python
&gt;&gt;&gt; from hashlib import *
&gt;&gt;&gt; h = chr(0x80 + 20)
&gt;&gt;&gt; h = sha256(sha256(h).digest()).digest()
&gt;&gt;&gt; h = new('ripemd160', sha256(h).digest()).digest()
&gt;&gt;&gt; h = sha256(h).digest()
&gt;&gt;&gt; h = sha1(h).digest()
&gt;&gt;&gt; h = new('ripemd160', h).digest()
&gt;&gt;&gt; print h.encode('hex')
16cfb9bc7654ef1d7723e5c2722fc0c3d505045e
</code></pre>

<p>As an aside: that's a rather, uhm, <em>interesting</em> script you've found....</p>

CC BY-SA 3.0
2015-05-16T07:42:42.787Z
heh yeah its interesting allright. thanks for pointing out where negative integers are handled in the original source code
mulllhausen
CC BY-SA 3.0
2015-05-15T16:56:53.523Z
2015-05-15T16:56:53.523Z
Christopher Gurnee
<p>This is an extremely useful site for debugging bitcoin scripts: <a href="http://webbtc.com/script">http://webbtc.com/script</a>.</p>

<p>Bitcoin uses a custom way to serialize integers, shown <a href="https://github.com/bitcoin/bitcoin/blob/v0.10.1/src/script/script.h#L287-L318">here</a>. This is confusing, but keeps the number of bytes on the stack small as possible. Let's walk through the basic execution:</p>

<pre><code>exec : 20 OP_NEGATE OP_HASH256
stack: 

exec : OP_NEGATE OP_HASH256
stack: 0x14

exec : OP_HASH256
stack: 0x94

exec : 
stack: 0xaf462e245a0f463a93e23a54eb0b4d0d8da7a951e4d0b41015782a27e80a2e2c
</code></pre>

<p>The confusing step is really the <code>OP_NEGATE</code>. To negate an integer that fits into 1 byte without having the MSB set, you just XOR with 0x80. Hence, <code>0x14 ^ 0x80 -&gt; 0x94</code>. </p>

<p>The script debugger I linked to above verifies this result. This python code verifies the result as well:</p>

<pre><code>import hashlib
import binascii

def SHA256d(string):
    bin = binascii.unhexlify(string)
    hash = hashlib.sha256(hashlib.sha256(bin).digest()).digest()
    raw = str(binascii.hexlify(hash))[2:-1]
    return raw

print (SHA256d("94"))
</code></pre>

<p>Prints:</p>

<pre><code>af462e245a0f463a93e23a54eb0b4d0d8da7a951e4d0b41015782a27e80a2e2c
</code></pre>

CC BY-SA 3.0
2015-05-15T16:58:42.627Z
Oops, it looks like you beat me to it :-)
Christopher Gurnee
CC BY-SA 3.0
2015-05-16T07:41:14.563Z
webbtc isn't heaps useful here as it writes `-20` instead of `0x94`. but your answer was very useful, thanks.
mulllhausen
CC BY-SA 3.0
2015-05-15T16:39:42.277Z
2015-05-15T16:39:42.277Z
morsecoder
<p><a href="http://blockexplorer.com/tx/61a078472543e9de9247446076320499c108b52307d8d0fafbe53b5c4e32acc4" rel="nofollow">transaction 9 in block 251684</a> spends <a href="http://blockexplorer.com/tx/5342c96b946ea2c5e497de5dbf7762021f94aba2c8222c17ed28492fdbb4a6d9" rel="nofollow">transaction 25 of block 249957</a>. the script to be evaluated here is:</p>

<pre><code>OP_PUSHDATA0(20) 16cfb9bc7654ef1d7723e5c2722fc0c3d505045e OP_SIZE OP_DUP OP_TRUE
OP_GREATERTHAN OP_VERIFY OP_NEGATE OP_HASH256 OP_HASH160 OP_SHA256 OP_SHA1
OP_RIPEMD160 OP_EQUAL
</code></pre>

<p>the problem i have is with how to sha256 a negative number. so far i have the following:</p>

<pre><code>op: OP_PUSHDATA0(20) 16cfb9bc7654ef1d7723e5c2722fc0c3d505045e,
                    new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e]
op: OP_SIZE,        new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, 20]
op: OP_DUP,         new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, 20, 20]
op: OP_TRUE,        new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, 20, 20, 1]
op: OP_GREATERTHAN, new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, 20, 1] (since 20 &gt; 1)
op: OP_VERIFY,      new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, 20]
op: OP_NEGATE,      new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, -20]
op: OP_HASH256,     new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, ???]
</code></pre>

<script>
OP_HASH256 of a negative number
mulllhausen
# OP_HASH256 of a negative number

(Asked by: username_0 on 2015-05-15)

[transaction 9 in block 251684](http://blockexplorer.com/tx/61a078472543e9de9247446076320499c108b52307d8d0fafbe53b5c4e32acc4) spends [transaction 25 of block 249957](http://blockexplorer.com/tx/5342c96b946ea2c5e497de5dbf7762021f94aba2c8222c17ed28492fdbb4a6d9). the script to be evaluated here is:

```
OP_PUSHDATA0(20) 16cfb9bc7654ef1d7723e5c2722fc0c3d505045e OP_SIZE OP_DUP OP_TRUE
OP_GREATERTHAN OP_VERIFY OP_NEGATE OP_HASH256 OP_HASH160 OP_SHA256 OP_SHA1
OP_RIPEMD160 OP_EQUAL

```

the problem i have is with how to sha256 a negative number. so far i have the following:

```
op: OP_PUSHDATA0(20) 16cfb9bc7654ef1d7723e5c2722fc0c3d505045e,
                    new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e]
op: OP_SIZE,        new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, 20]
op: OP_DUP,         new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, 20, 20]
op: OP_TRUE,        new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, 20, 20, 1]
op: OP_GREATERTHAN, new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, 20, 1] (since 20 > 1)
op: OP_VERIFY,      new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, 20]
op: OP_NEGATE,      new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, -20]
op: OP_HASH256,     new stack: [0x16cfb9bc7654ef1d7723e5c2722fc0c3d505045e, ???]

```

**Tags:** script


---

## 2 answers

### Answer by username_2 on 2015-05-15. Score: 6 | Accepted answer

This is an extremely useful site for debugging bitcoin scripts: <http://webbtc.com/script>.

Bitcoin uses a custom way to serialize integers, shown [here](https://github.com/bitcoin/bitcoin/blob/v0.10.1/src/script/script.h#L287-L318). This is confusing, but keeps the number of bytes on the stack small as possible. Let's walk through the basic execution:

```
exec : 20 OP_NEGATE OP_HASH256
stack: 

exec : OP_NEGATE OP_HASH256
stack: 0x14

exec : OP_HASH256
stack: 0x94

exec : 
stack: 0xaf462e245a0f463a93e23a54eb0b4d0d8da7a951e4d0b41015782a27e80a2e2c

```

The confusing step is really the `OP_NEGATE`. To negate an integer that fits into 1 byte without having the MSB set, you just XOR with 0x80. Hence, `0x14 ^ 0x80 -> 0x94`.

The script debugger I linked to above verifies this result. This python code verifies the result as well:

```
import hashlib
import binascii

def SHA256d(string):
    bin = binascii.unhexlify(string)
    hash = hashlib.sha256(hashlib.sha256(bin).digest()).digest()
    raw = str(binascii.hexlify(hash))[2:-1]
    return raw

print (SHA256d("94"))

```

Prints:

```
af462e245a0f463a93e23a54eb0b4d0d8da7a951e4d0b41015782a27e80a2e2c

```

> **Comments:**
> **username_1**: Oops, it looks like you beat me to it :-)  
> **username_0**: webbtc isn't heaps useful here as it writes `-20` instead of `0x94`. but your answer was very useful, thanks.  

---

### Answer by username_1 on 2015-05-15. Score: 3

The value that is hashed is the single byte `0x94`.

The stack contains vectors of unsigned chars. OP\_NEGATE converts the int `-20` into a vector of unsigned chars by calling `CScriptNum::getvch()` [here](https://github.com/bitcoin/bitcoin/blob/v0.10.1/src/script/interpreter.cpp#L671):

```
stack.push_back(bn.getvch());

```

`CScriptNum::getvch()` [serializes ints into bytes](https://github.com/bitcoin/bitcoin/blob/v0.10.1/src/script/script.h#L282-L318) by taking its absolute value, encoding the result in [little-endian](https://en.wikipedia.org/wiki/Endianness) form using the fewest number of bytes possible, and then guarantying that the most significant bit of the most significant byte is set if and only if the value is negative.

Therefore `-20` is serialized into the single byte `0x80 + 20 == 0x94`.

This can be further verified by completing the rest of the script:

```
$ python
>>> from hashlib import *
>>> h = chr(0x80 + 20)
>>> h = sha256(sha256(h).digest()).digest()
>>> h = new('ripemd160', sha256(h).digest()).digest()
>>> h = sha256(h).digest()
>>> h = sha1(h).digest()
>>> h = new('ripemd160', h).digest()
>>> print h.encode('hex')
16cfb9bc7654ef1d7723e5c2722fc0c3d505045e

```

As an aside: that's a rather, uhm, *interesting* script you've found....

> **Comments:**
> **username_0**: heh yeah its interesting allright. thanks for pointing out where negative integers are handled in the original source code  

---

