summaryrefslogtreecommitdiff
path: root/58/c92d1426d1cc640535bf2cfdeb792e4c657cd0
blob: 35ff94fe38b63fcc48be53867c99dc64e39c18bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
Return-Path: <jlrubin@mit.edu>
Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136])
 by lists.linuxfoundation.org (Postfix) with ESMTP id B2546C000B
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sat, 24 Apr 2021 20:05:42 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
 by smtp3.osuosl.org (Postfix) with ESMTP id A029860791
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sat, 24 Apr 2021 20:05:42 +0000 (UTC)
X-Virus-Scanned: amavisd-new at osuosl.org
X-Spam-Flag: NO
X-Spam-Score: -4.199
X-Spam-Level: 
X-Spam-Status: No, score=-4.199 tagged_above=-999 required=5
 tests=[BAYES_00=-1.9, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_MED=-2.3,
 SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Received: from smtp3.osuosl.org ([127.0.0.1])
 by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id kOWD-GLDZNKV
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sat, 24 Apr 2021 20:05:39 +0000 (UTC)
X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0
Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11])
 by smtp3.osuosl.org (Postfix) with ESMTPS id 87BAE60782
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sat, 24 Apr 2021 20:05:39 +0000 (UTC)
Received: from mail-io1-f45.google.com (mail-io1-f45.google.com
 [209.85.166.45]) (authenticated bits=0)
 (User authenticated as jlrubin@ATHENA.MIT.EDU)
 by outgoing.mit.edu (8.14.7/8.12.4) with ESMTP id 13OK5bXA018973
 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NOT)
 for <bitcoin-dev@lists.linuxfoundation.org>; Sat, 24 Apr 2021 16:05:37 -0400
Received: by mail-io1-f45.google.com with SMTP id t21so1314933iob.2
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sat, 24 Apr 2021 13:05:37 -0700 (PDT)
X-Gm-Message-State: AOAM531FvZcj6PuNqUqmLYLf7TOBPm9wQg1IedW2NssOt5c09xy+DHUT
 6ZzcWy/t+E/W7hNWPSDxyJpgRLiGjhNng0k0Rog=
X-Google-Smtp-Source: ABdhPJxwTJ9H7jAAAN1iw5kiR6GaO/RjowlhP3IrW40CbB/O9wkV51/JypYoYbZvOR0pkP/4uqUFVZWEwe6isNwpVIA=
X-Received: by 2002:a6b:7b45:: with SMTP id m5mr8099798iop.97.1619294737109;
 Sat, 24 Apr 2021 13:05:37 -0700 (PDT)
MIME-Version: 1.0
References: <CAD5xwhj7jXSrdbfFJTYw-UzGgZTF0kz-Vr61juF0gJGLf2EKqQ@mail.gmail.com>
 <20210423181550.xri2ravlwfe3vpc6@ganymede>
In-Reply-To: <20210423181550.xri2ravlwfe3vpc6@ganymede>
From: Jeremy <jlrubin@mit.edu>
Date: Sat, 24 Apr 2021 13:05:25 -0700
X-Gmail-Original-Message-ID: <CAD5xwhgnL_u1hS99HPTMBfQbRohgmajzNX4XiGYnN9mZDqjC7g@mail.gmail.com>
Message-ID: <CAD5xwhgnL_u1hS99HPTMBfQbRohgmajzNX4XiGYnN9mZDqjC7g@mail.gmail.com>
To: "David A. Harding" <dave@dtrt.org>
Content-Type: multipart/alternative; boundary="00000000000097972105c0bd6f22"
Cc: Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>
Subject: Re: [bitcoin-dev] [Pre-BIP] Motivating Address type for OP_RETURN
X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org>
List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>, 
 <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe>
List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/>
List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org>
List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help>
List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>, 
 <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe>
X-List-Received-Date: Sat, 24 Apr 2021 20:05:42 -0000

--00000000000097972105c0bd6f22
Content-Type: text/plain; charset="UTF-8"

Inline responses

On Fri, Apr 23, 2021, 11:18 AM David A. Harding <dave@dtrt.org> wrote:

> On Tue, Apr 20, 2021 at 08:46:07AM -0700, Jeremy via bitcoin-dev wrote:
>
>
>
>
>
> * > Script is technically "too wide" a type as what I really want is to >
> only return coins with known output types. I don't understand this
> concern.  If script is too wide a type, then OP_RETURN being a scriptPubKey
> of arbitrary length up to almost a million bytes is also going to be too
> wide, right?*
>


I meant the type itself is too wide, not the length of the value. As in
Script can represent things we know nothing about. There's a bit of leaky
abstraction since the values self describe the type they are. For addresses
it's just representations IMO for the standard output types one might
expect from standard software.

Btw: According to... Oh wait... You?
https://bitcoin.stackexchange.com/questions/35878/is-there-a-maximum-size-of-a-scriptsig-scriptpubkey
the max size is 10k bytes. Still probably too big for an address, but I'd
be ok with making op_return addresses only defined for a small size (e.g.
128 bytes?)



>
>
>
>
>
>
>
>
>
>
>
>
>
>
> * > 1) Should it be human readable & checksummed or encoded? It should
> absolutely not be human readable in the sense of being meaningful to
> humans.  We've seen in the past that tools and sites that display OP_RETURN
> data as ASCII encourage people to put text in the block chain that is
> offensive and illegal.  This puts people running nodes at risk of social
> and legal intervention.  Bitcoin's premissionless nature means we can't
> stop people from creating such problems, but we can lower the risk by
> having our tools default to meaningless representations of OP_RETURN data.
> The best advice I've seen is to display OP_RETURN data in hex.  It's still
> possible to say things like "dead beef" with that, but significant abuse is
> hard.  This will, of course, make even 80 byte OP_RETURN "addresses" very
> long.*
>

Is it possible/easy to, say, using bech32m make an inappropriate message in
the address? You'd have to write the message, then see what it decodes to
without checking, and then re encode? I guess this is worse than hex?

But it seems this is a general thing... If you wanted an inappropriate
message you could therefore just use bech32m addressed outputs.


> >
>
>
>
> * 2) Should it have a fixed length of max 40-80 bytes or should we support
> > arbitrary length strings? If it doesn't support the fell range,
> somebody's just going to complain later and there will have to be a v2
> address.*
>

So 10,000 bytes? Or do we care to represent outputs that would be consensus
invalid?



>
>
>
>
>
>
>
>
>
>
>
> * > 3) Should it be possible (i.e., from core) to pay into such an
> OP_RETURN or > should we categorize OP_RETURNS as a non-payable address
> type (and just use > it for parsing blockdata) I don't think including
> arbitrary data in the block chain is something that's currently useful for
> typical end users, and applications that want to use OP_RETURN with Bitcoin
> Core can already call create(psbt|rawtransaction) with the `data` field, so
> I'd be mildly opposed in including such a feature in Bitcoin Core's
> wallet.  If at least a few other wallets add the feature to pay OP_RETURN
> "addresses" and it seems popular, then I'm wrong and so I would probably
> then change my position.*
>

One of the nice things is that the current psbt interface uses a blind
union type whereby the entires in an array are either [address, amount] or
["data", hex]. Having an address type would allow more uniform handling,
which is convenient for strongly typed RPC bindings (e.g. rust bitcoin uses
a hashmap of address to amount so without a patch you can't create op
returns).


>
>
>
>
>
> * Regarding "parsing block data", I don't think there's any need to change
> Bitcoin Core's current representation of OP_RETURN outputs (which is just
> showing the hex-encoded script in RPC output).  For any program needing
> OP_RETURN output, hex format is going to be a the next best thing to
> getting it in raw binary.  Any other address format is going to be equal or
> more work*.
>

Thats a fair point. I'm mostly thinking about this in the context of
strongly typed languages/frameworks where you'll get an address object or
enum out, rather than something *stringly* typed. But yes in terms of
stringy languages I don't think any changes are needed.

*Additionally, as mentioned in the other thread about OP_RETURN this*
*week, increasing transaction fees should increasingly push uses of*
*OP_RETURN off the network or into more efficient constructions, so it*
*doesn't seem warranted to me to spend a lot of time trying to optimize*
*how we use it when we'll be using it less and less over time.*


Hmm. I agree it should get priced out over time. However there are some
uses for this kind of stuff. E.g. stealth addresses, or a single instance
of open time stamps.

The main reason I think they merit some sort of std address type is that
I'm writing software that can handle things that we might reasonably see on
the network. And it's relatively annoying (without a custom type) to
represent OP_RETURN as a not-exceptional type of thing.

In my code what I have done is added the following type:

pub enum ExtendedAddress {
/// A regular standard address type
Address(bitcoin::Address),
/// An OP_RETURN
OpReturn(OpReturn),
/// Unknown
Unknown(bitcoin::Script),
}
Which works more or less fine, but I would much prefer to not have to do
this in a custom way, as opposed to a way which is defined in a standard
manner across all software (after all, that's the point of standards).

Best,

Jeremy

--00000000000097972105c0bd6f22
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"auto"><div>Inline response<span class=3D"gmail=
_default" style=3D"font-family:arial,helvetica,sans-serif;font-size:small;c=
olor:rgb(0,0,0)">s</span><br><br><div class=3D"gmail_quote"><div dir=3D"ltr=
" class=3D"gmail_attr">On Fri, Apr 23, 2021, 11:18 AM David A. Harding &lt;=
<a href=3D"mailto:dave@dtrt.org" target=3D"_blank">dave@dtrt.org</a>&gt; wr=
ote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex">On Tue, Apr 20, 2021 at 08:46:=
07AM -0700, Jeremy via bitcoin-dev wrote:<br><i>
&gt; Script is technically &quot;too wide&quot; a type as what I really wan=
t is to<br>
&gt; only return coins with known output types.<br>
<br>
I don&#39;t understand this concern.=C2=A0 If script is too wide a type, th=
en<br>
OP_RETURN being a scriptPubKey of arbitrary length up to almost a<br>
million bytes is also going to be too wide, right?</i><br></blockquote></di=
v></div><div dir=3D"auto"><br></div><div dir=3D"auto"><br></div><div dir=3D=
"auto">I meant the type itself is too wide, not the length of the value. As=
 in Script can represent things we know nothing about. There&#39;s a bit of=
 leaky abstraction since the values self describe the type they are. For ad=
dresses it&#39;s just representations IMO for the standard output types one=
 might expect from standard software.=C2=A0</div><div dir=3D"auto"><br></di=
v><div dir=3D"auto">Btw: According to... Oh wait... You?</div><div dir=3D"a=
uto"><a href=3D"https://bitcoin.stackexchange.com/questions/35878/is-there-=
a-maximum-size-of-a-scriptsig-scriptpubkey" target=3D"_blank">https://bitco=
in.stackexchange.com/questions/35878/is-there-a-maximum-size-of-a-scriptsig=
-scriptpubkey</a> the max size is 10k bytes. Still probably too big for an =
address, but I&#39;d be ok with making op_return addresses only defined for=
 a small size (e.g. 128 bytes?)</div><div dir=3D"auto"><br></div><div dir=
=3D"auto"><br></div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquot=
e class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc sol=
id;padding-left:1ex">
<i><br>
&gt; 1) Should it be human readable &amp; checksummed or encoded?<br>
<br>
It should absolutely not be human readable in the sense of being<br>
meaningful to humans.=C2=A0 We&#39;ve seen in the past that tools and sites=
 that<br>
display OP_RETURN data as ASCII encourage people to put text in the<br>
block chain that is offensive and illegal.=C2=A0 This puts people running<b=
r>
nodes at risk of social and legal intervention.=C2=A0 Bitcoin&#39;s<br>
premissionless nature means we can&#39;t stop people from creating such<br>
problems, but we can lower the risk by having our tools default to<br>
meaningless representations of OP_RETURN data.<br>
<br>
The best advice I&#39;ve seen is to display OP_RETURN data in hex.=C2=A0 It=
&#39;s<br>
still possible to say things like &quot;dead beef&quot; with that, but sign=
ificant<br>
abuse is hard.=C2=A0 This will, of course, make even 80 byte OP_RETURN<br>
&quot;addresses&quot; very long.</i><br></blockquote></div></div><div dir=
=3D"auto"><br></div><div dir=3D"auto">Is it possible/easy to, say, using be=
ch32m make an inappropriate message in the address? You&#39;d have to write=
 the message, then see what it decodes to without checking, and then re enc=
ode? I guess this is worse than hex?</div><div dir=3D"auto"><br></div><div =
dir=3D"auto">But it seems this is a general thing... If you wanted an inapp=
ropriate message you could therefore just use bech32m addressed outputs.</d=
iv><div dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"gmail_quote"=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex">
<br>
&gt;<i> 2) Should it have a fixed length of max 40-80 bytes or should we su=
pport<br>
&gt; arbitrary length strings?<br>
<br>
If it doesn&#39;t support the fell range, somebody&#39;s just going to comp=
lain<br>
later and there will have to be a v2 address.</i><br></blockquote></div></d=
iv><div dir=3D"auto"><br></div><div dir=3D"auto">So 10,000 bytes? Or do we =
care to represent outputs that would be consensus invalid?</div><div dir=3D=
"auto"><br></div><div dir=3D"auto"><br></div><div dir=3D"auto"><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex">
<i><br>
&gt; 3) Should it be possible (i.e., from core) to pay into such an OP_RETU=
RN or<br>
&gt; should we categorize OP_RETURNS as a non-payable address type (and jus=
t use<br>
&gt; it for parsing blockdata)<br>
<br>
I don&#39;t think including arbitrary data in the block chain is something<=
br>
that&#39;s currently useful for typical end users, and applications that<br=
>
want to use OP_RETURN with Bitcoin Core can already call<br>
create(psbt|rawtransaction) with the `data` field, so I&#39;d be mildly<br>
opposed in including such a feature in Bitcoin Core&#39;s wallet.=C2=A0 If =
at<br>
least a few other wallets add the feature to pay OP_RETURN &quot;addresses&=
quot;<br>
and it seems popular, then I&#39;m wrong and so I would probably then chang=
e<br>
my position.</i><br></blockquote></div></div><div dir=3D"auto"><br></div><d=
iv dir=3D"auto">One of the nice things is that the current psbt interface u=
ses a blind union type whereby the entires in an array are either [address,=
 amount] or [&quot;data&quot;, hex]. Having an address type would allow mor=
e uniform handling, which is convenient for strongly typed RPC bindings (e.=
g. rust bitcoin uses a hashmap of address to amount so without a patch you =
can&#39;t create op returns).</div><div dir=3D"auto"><br></div><div dir=3D"=
auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D=
"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br><i>
Regarding &quot;parsing block data&quot;, I don&#39;t think there&#39;s any=
 need to change<br>
Bitcoin Core&#39;s current representation of OP_RETURN outputs (which is<br=
>
just showing the hex-encoded script in RPC output).=C2=A0 For any program<b=
r>
needing OP_RETURN output, hex format is going to be a the next best<br>
thing to getting it in raw binary.=C2=A0 Any other address format is going =
to<br>
be equal or more work</i>.<br></blockquote></div></div><div dir=3D"auto"><b=
r></div><div dir=3D"auto">Thats a fair point. I&#39;m mostly thinking about=
 this in the context of strongly typed languages/frameworks where you&#39;l=
l get an address object or enum out, rather than something *stringly* typed=
. But yes in terms of stringy languages I don&#39;t think any changes are n=
eeded.=C2=A0</div><div dir=3D"auto"><br></div><div dir=3D"auto"><i>Addition=
ally, as mentioned in the other thread about OP_RETURN this</i></div><div d=
ir=3D"auto"><i>week, increasing transaction fees should increasingly push u=
ses of</i></div><div dir=3D"auto"><i>OP_RETURN off the network or into more=
 efficient constructions, so it</i></div><div dir=3D"auto"><i>doesn&#39;t s=
eem warranted to me to spend a lot of time trying to optimize</i></div><div=
 dir=3D"auto"><i>how we use it when we&#39;ll be using it less and less ove=
r time.</i></div><div dir=3D"auto"><br></div><div dir=3D"auto"><br></div><d=
iv dir=3D"auto">Hmm. I agree it should get priced out over time. However th=
ere are some uses for this kind of stuff. E.g. stealth addresses, or a sing=
le instance of open time stamps.=C2=A0</div><div dir=3D"auto"><br></div><di=
v dir=3D"auto">The main reason I think they merit some sort of std address =
type is that I&#39;m writing software that can handle things that we might =
reasonably see on the network. And it&#39;s relatively annoying (without a =
custom type) to represent OP_RETURN<span class=3D"gmail_default" style=3D"f=
ont-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)"> as=
 a not-exceptional type of thing. </span></div><div dir=3D"auto"><br></div>=
<div dir=3D"auto"><div style=3D"font-family:arial,helvetica,sans-serif;font=
-size:small;color:rgb(0,0,0)" class=3D"gmail_default">In my code what I hav=
e done is added the following type:</div></div><div dir=3D"auto"><br></div>=
<div dir=3D"auto"><div style=3D"font-family:arial,helvetica,sans-serif;font=
-size:small;color:rgb(0,0,0)" class=3D"gmail_default"><div style=3D"color:r=
gb(187,187,187);background-color:rgb(40,44,52);font-family:&quot;IBM Plex M=
ono Text&quot;,&quot;Droid Sans Mono&quot;,&quot;monospace&quot;,monospace,=
&quot;Droid Sans Fallback&quot;;font-weight:normal;font-size:12px;line-heig=
ht:20px;white-space:pre"><div><span style=3D"color:rgb(198,120,221)">pub</s=
pan><span style=3D"color:rgb(187,187,187)"> </span><span style=3D"color:rgb=
(198,120,221)">enum</span><span style=3D"color:rgb(187,187,187)"> </span><s=
pan style=3D"color:rgb(229,192,123)">ExtendedAddress</span><span style=3D"c=
olor:rgb(187,187,187)"> {</span></div><div><span style=3D"color:rgb(92,99,1=
12);font-style:italic">    /// A regular standard address type</span></div>=
<div><span style=3D"color:rgb(187,187,187)">    </span><span style=3D"color=
:rgb(97,175,239)">Address</span><span style=3D"color:rgb(187,187,187)">(bit=
coin</span><span style=3D"color:rgb(171,178,191)">::</span><span style=3D"c=
olor:rgb(229,192,123)">Address</span><span style=3D"color:rgb(187,187,187)"=
>),</span></div><div><span style=3D"color:rgb(92,99,112);font-style:italic"=
>    /// An OP_RETURN</span></div><div><span style=3D"color:rgb(187,187,187=
)">    </span><span style=3D"color:rgb(97,175,239)">OpReturn</span><span st=
yle=3D"color:rgb(187,187,187)">(</span><span style=3D"color:rgb(229,192,123=
)">OpReturn</span><span style=3D"color:rgb(187,187,187)">),</span></div><di=
v><span style=3D"color:rgb(92,99,112);font-style:italic">    /// Unknown</s=
pan></div><div><span style=3D"color:rgb(187,187,187)">    </span><span styl=
e=3D"color:rgb(97,175,239)">Unknown</span><span style=3D"color:rgb(187,187,=
187)">(bitcoin</span><span style=3D"color:rgb(171,178,191)">::</span><span =
style=3D"color:rgb(229,192,123)">Script</span><span style=3D"color:rgb(187,=
187,187)">),</span></div><div><span style=3D"color:rgb(187,187,187)">}</spa=
n></div></div></div><div style=3D"font-family:arial,helvetica,sans-serif;fo=
nt-size:small;color:rgb(0,0,0)" class=3D"gmail_default">Which works more or=
 less fine, but I would much prefer to not have to do this in a custom way,=
 as opposed to a way which is defined in a standard manner across all softw=
are (after all, that&#39;s the point of standards).<br></div><div style=3D"=
font-family:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" cl=
ass=3D"gmail_default"><br></div><div style=3D"font-family:arial,helvetica,s=
ans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmail_default">Best,</=
div><div style=3D"font-family:arial,helvetica,sans-serif;font-size:small;co=
lor:rgb(0,0,0)" class=3D"gmail_default"><br></div><div style=3D"font-family=
:arial,helvetica,sans-serif;font-size:small;color:rgb(0,0,0)" class=3D"gmai=
l_default">Jeremy<br></div></div></div>
</div>

--00000000000097972105c0bd6f22--