Bitcoin Forum
May 27, 2019, 12:36:46 PM *
News: Latest Bitcoin Core release: 0.18.0 [Torrent] (New!)
 
   Home   Help Search Login Register More  
Pages: [1] 2 3 »  All
  Print  
Author Topic: Delayed transactions (using nTimeLock)  (Read 13144 times)
halftimepad
Newbie
*
Offline Offline

Activity: 20
Merit: 0


View Profile
December 18, 2012, 05:15:26 PM
 #1

Hello all. I'm new in the Bitcoin community and I have a particular interest in contracts, Script and all the new possibilities that usual currencies don't have.

I have been looking into some features like the ability to delay payments. In principle, transactions have a lock time that can be used to delay transactions.

https://en.bitcoin.it/wiki/Protocol_specification#tx

There are some interesting uses in contracts in transaction replacement, but this ability seems to be disabled at the moment http://bitcoin.stackexchange.com/questions/861/why-isnt-transaction-replacement-supported.

I have made a small block explorer based on bitcointools (https://github.com/gavinandresen/bitcointools) to find transactions with a lock_time value different from 0 and have found five transactions that do have a wait time. They are in blocks:

000000000000036a546044e094db778e1c146f051cd5d0e52fb0e6c43e63ea8c
000000000000049bd7c8aebf91efc907c880a35c05b7861b4eab3fc09655bb05
00000000000005f229df518de50c53616f4f2f895deca078dce1d74d5b79e39c
000000000000026e8536f6ffe741feeb30d7123e6435b3ad7db141833969b5bf
00000000000001d985839442aac0179713fc7f6e5b109d524a272d3d55600d7a

The transactions are:

Code:

http://blockexplorer.com/rawblock/000000000000036a546044e094db778e1c146f051cd5d0e52fb0e6c43e63ea8c

{
      "hash":"13e100dd08b6da0a7426ea520b0bb3ae54cef79dd045e2e4f7116023df3a5c95",
      "ver":1,
      "vin_sz":1,
      "vout_sz":1,
      "lock_time":198370,
      "size":191,
      "in":[
        {
          "prev_out":{
            "hash":"8af03f89f3e774ba64890b6f491f43b30de5f8c5e1d92fcad1e3355c566fd21d",
            "n":1
          },
          "scriptSig":"304402204427e4bcb2bd48bf5d25dc3c7fde90df5b6e8ad39f62ddf1ad2bf82c33bb7f170220494ac767bbbe269eb8c352c8698ed24f2be09ee5d4e5f6a5d7cf69e709c28f1201 021669049d34ea3a8e364710151de215f15a74947ab87b8952ab062ed106c37bf6"
        }
      ],
      "out":[
        {
          "value":"0.01500000",
          "scriptPubKey":"OP_DUP OP_HASH160 46186d1c563e4507b102aa0e5e3b9ef0a9077de3 OP_EQUALVERIFY OP_CHECKSIG"
        }
      ]
    },


http://blockexplorer.com/rawblock/000000000000049bd7c8aebf91efc907c880a35c05b7861b4eab3fc09655bb05

  {
      "hash":"34df83aea6d6a68bab10b01e4ec4043850855406d45589b907dea565c8439976",
      "ver":1,
      "vin_sz":2,
      "vout_sz":1,
      "lock_time":199000,
      "size":341,
      "in":[
        {
          "prev_out":{
            "hash":"69d771de96b5e0b7e66bc47f13eeedb96c45636bb3853637852b536b8959026a",
            "n":0
          },
          "scriptSig":"3046022100ea4a9a35edbfa63327a68ef33b151da6a824ba86119c2fb2e69ccfa676cbf55d022100d8071b560b35585bee1249ba27e4cd9b61229c4bad6a5e2482982ea98e59215f01 024931bfb3b26c333c180a9dce4892035f58468cb1bd0b5e2159f5834101672a40"
        },
        {
          "prev_out":{
            "hash":"69d771de96b5e0b7e66bc47f13eeedb96c45636bb3853637852b536b8959026a",
            "n":1
          },
          "scriptSig":"304502207674f68e100d65b0f29316b0d643d3e6c9410da056102ab305d4ea8f229f5c56022100ddbd064ae427f4db44fc8cefd45e837e35264b276ed8007fbf293301b22bd82901 025145729dd299d26dd21244e04df616a6083e80e2604153d1ec9b20dc79d1f4e2"
        }
      ],
      "out":[
        {
          "value":"0.01450000",
          "scriptPubKey":"OP_DUP OP_HASH160 1bec313498b523aadb2964ab6d95608a911f4eeb OP_EQUALVERIFY OP_CHECKSIG"
        }
      ]
    },


http://blockexplorer.com/rawblock/00000000000005f229df518de50c53616f4f2f895deca078dce1d74d5b79e39c

  {
      "hash":"b0fa60f601d5fe6fb1501aa614503b9af688492f68bcf8268d7cdb30f3534079",
      "ver":1,
      "vin_sz":1,
      "vout_sz":1,
      "lock_time":199000,
      "size":192,
      "in":[
        {
          "prev_out":{
            "hash":"4ac2fd4616a400ea29ad5eaff723d18ca05e4c22e4c9a190b8ab7b09d8964f99",
            "n":0
          },
          "scriptSig":"3045022006f942260b9587f8976fc31de7c238e4998e6f0afbf026568c41f732de672473022100f30f27305dc27b3435b5803fe72d0dacf8c845b402959d192d27de96f5fcd90601 03e71226d01c0186a3995446089d41ce90d08cf384f5a1c906239e540221efc683",
          "sequence":4278190335
        }
      ],
      "out":[
        {
          "value":"0.01350000",
          "scriptPubKey":"OP_DUP OP_HASH160 87965d6172fcc30cbbdfd1b674d66d567e64bb53 OP_EQUALVERIFY OP_CHECKSIG"
        }
      ]
    },


http://blockexplorer.com/rawblock/000000000000026e8536f6ffe741feeb30d7123e6435b3ad7db141833969b5bf

 {
      "hash":"c466c6f8ee76ac77495f703aa5646926d67730ea7a8ede45debf3be37c9ffe7b",
      "ver":1,
      "vin_sz":2,
      "vout_sz":2,
      "lock_time":207150,
      "size":373,
      "in":[
        {
          "prev_out":{
            "hash":"a8f8a86ebc2c9eb8989a6e988238cfa37ffc5634bd8a216a19a63ae7bb84e352",
            "n":0
          },
          "scriptSig":"304502206bbfb4f4c700b25d7e7c6627a43c6b6ef5c2e449c8c3cf0e729a08fd6b8e4d3f022100de614f17b6f2ddcf0c9cb5c9259ccbcf38fc7bc529c261166651072eee8de3a901 0372517b2117c312844838b6cb79959ab6dfb3357e7c7e8ead94e438091039f72d",
          "sequence":0
        },
        {
          "prev_out":{
            "hash":"a8f8a86ebc2c9eb8989a6e988238cfa37ffc5634bd8a216a19a63ae7bb84e352",
            "n":1
          },
          "scriptSig":"304402207dd414f7c962b67378bf659c7f38fd96a32e9c6d245479ce9f37595f6673e51f02202ea6355791b2b945694916baec0139ba6a807c35cc72b6e96ccaee21bb00409001 0346559defaa3a93fe93eb38af8f10ac060a39b2f5b1b18a932aaba39746e9f36f",
          "sequence":0
        }
      ],
      "out":[
        {
          "value":"0.00050000",
          "scriptPubKey":"OP_DUP OP_HASH160 f1ddb423647b717589222293108b3a71f6c9c479 OP_EQUALVERIFY OP_CHECKSIG"
        },
        {
          "value":"0.00022074",
          "scriptPubKey":"OP_DUP OP_HASH160 0c7d886ae9a809429e962458f8b86ecb7ae2b730 OP_EQUALVERIFY OP_CHECKSIG"
        }
      ]
    },

http://blockexplorer.com/rawblock/00000000000001d985839442aac0179713fc7f6e5b109d524a272d3d55600d7a

    {
      "hash":"d1ef46055a84fd02ee82580d691064780def18614d98646371c3448ca20019ac",
      "ver":1,
      "vin_sz":1,
      "vout_sz":2,
      "lock_time":207167,
      "size":226,
      "in":[
        {
          "prev_out":{
            "hash":"18a3db0f83fd7407f1a286af161703e19f5ea800944e9c273c02f3d2cd106a33",
            "n":1
          },
          "scriptSig":"3045022016dfc9cd05189641188b7f8ca8336d30c6dd4750766060437f16c384c4e9756a022100cbc2906d947e131bdf5e8a685df7ae869d3a92fdc7d0198cd7756ecf7f3fecef01 0372517b2117c312844838b6cb79959ab6dfb3357e7c7e8ead94e438091039f72d",
          "sequence":0
        }
      ],
      "out":[
        {
          "value":"0.00050000",
          "scriptPubKey":"OP_DUP OP_HASH160 2aacd8e8e3607cadd993eaf20047b3ba051049b5 OP_EQUALVERIFY OP_CHECKSIG"
        },
        {
          "value":"0.00900000",
          "scriptPubKey":"OP_DUP OP_HASH160 71b13ab7f1f5b1e7ed1b3df8c2b57eef083cf3fb OP_EQUALVERIFY OP_CHECKSIG"
        }
      ]
    },

It seems none of them will be able to be redeemed for a long time.

I have a few questions:

- This ability looks like a feature to me, but it seems clients shouldn't allow this kind of transaction and some people treat this as a bug:

http://bitcoin.stackexchange.com/questions/5783/transactions-with-a-wait-time-using-nlocktime/5833#5833
https://github.com/bitcoin/bitcoin/issues/1820

Are locked transactions supposed to be supported or not?

- If not, what will happen to the already existing locked transactions?

- Can you easily introduce a locked transaction using the standard client? If not, how? 



                       Thanks!
1558960606
Hero Member
*
Offline Offline

Posts: 1558960606

View Profile Personal Message (Offline)

Ignore
1558960606
Reply with quote  #2

1558960606
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
theymos
Administrator
Legendary
*
Offline Offline

Activity: 3402
Merit: 5638


View Profile
January 03, 2013, 08:30:58 PM
 #2

Quote
It seems none of them will be able to be redeemed for a long time.

That's not how lockTime works. lockTime prevents a transaction from getting into blocks. Once it's in a block, it can be spent.

These transactions were always final because all of their inputs have sequence numbers of UINT_MAX:
000000000000036a546044e094db778e1c146f051cd5d0e52fb0e6c43e63ea8c
000000000000049bd7c8aebf91efc907c880a35c05b7861b4eab3fc09655bb05

The other transactions all became final two blocks before the blocks that they were added to.

1NXYoJ5xU91Jp83XfVMHwwTUyZFK64BoAD
Gavin Andresen
Legendary
*
qt
Offline Offline

Activity: 1652
Merit: 1019


Chief Scientist


View Profile WWW
January 03, 2013, 09:21:28 PM
 #3

theymos is correct; if all the inputs have a UINT_MAX sequence number then lockTime is ignored.

Quote
Are locked transactions supposed to be supported or not?

Yes, they're supported by the network.

Quote
- Can you easily introduce a locked transaction using the standard client? If not, how?

No, there is no easy way to create such a transaction using the reference code.

* Super-duper-bitcoin-ninjas like gmaxwell who edit raw transaction hex to set lock times / sequence numbers don't count.

How often do you get the chance to work on a potentially world-changing project?
Mike Hearn
Legendary
*
expert
Offline Offline

Activity: 1526
Merit: 1008


View Profile
January 03, 2013, 09:24:52 PM
 #4

You could try writing a bitcoinj app if you want to play with these features. It's an API designed to make doing that kind of thing easy.
etotheipi
Legendary
*
expert
Offline Offline

Activity: 1428
Merit: 1005


Core Armory Developer


View Profile WWW
January 04, 2013, 06:32:32 AM
Last edit: January 04, 2013, 03:57:00 PM by etotheipi
 #5

One thing that wasn't mentioned yet was that there's not currently a mechanism for replacement.  Locked transactions can be "introduced" into the blockchain fairly easily, and nodes will accept them and hold them in their memory pool (and thus drop conflicting transactions), but they won't forward otherwise-valid replacements, and only miners with custom rules will mine them for you.  If you want to replace a time-locked transaction, you're going to have to mine it yourself, or go find a miner to agree to help you.  Once a replacement is mined (or even just a regular transaction spending one of the inputs), all nodes holding the time-locked tx will see the conflict and drop the one in their memory pool.

So, if you can create the tx, you can get the "time-delay" aspect out of the network right now, but you have to work pretty hard if you use the "replacement" aspect of it.

P.S. - Congrats on being the most well-spoken, research-driven, single-post Newbie I've seen on these forums Smiley

Founder and CEO of Armory Technologies, Inc.
Armory Bitcoin Wallet: Bringing cold storage to the average user!
Only use Armory software signed by the Armory Offline Signing Key (0x98832223)

Please donate to the Armory project by clicking here!    (or donate directly via 1QBDLYTDFHHZAABYSKGKPWKLSXZWCCJQBX -- yes, it's a real address!)
gmaxwell
Moderator
Legendary
*
qt
Offline Offline

Activity: 2744
Merit: 2268



View Profile
January 04, 2013, 03:47:00 PM
 #6

- Can you easily introduce a locked transaction using the standard client? If not, how?
I thought everyone else had good answeres to your other questions... but you can create locked transactions using createraw transaction and then just manually editing the hex transaction.  You'll need to consult the bitcoin wiki on the layout but it's quite easy to adjust the locktime and sequence by hand and decoderawtransaction will show you your success.
halftimepad
Newbie
*
Offline Offline

Activity: 20
Merit: 0


View Profile
January 05, 2013, 11:55:09 PM
 #7

Thank you all for the explanations!

  I have already been playing with raw transactions in the testnet with bitcoind. After a few false starts (I still have some trouble with the change and I forgot about the sequence number) I think I have managed to send some transactions with a lock time.

  I'm still a bit confused, because right after sending them, I could spend the coins in another transaction. Here is an example transaction:

Code:
{
    "hex" : "0100000001b110f593f3f4b0a9f93fd625d5e455c82b7ec0a5fe491198ac0bdf042bc837c8000000006b48304502207501c32e46cfba0ac5aae64849a34107c2a30291448604d0c207ae7c0a05c65d022100f914d06a0f64331d0b6ba931d62db2257293c199d4541bbb02266cf0fa1272f50121035ecd174d977eecdda204fd52be159469b77399f8f19894a70b72216197525782fff0ffff0100d2496b000000001976a914be42ebf8ab45f191de4703213a093510b825959188ac03000000",
    "txid" : "251a368ff8a663f8d1ce55ce1f3dbd49ce2fbd9f1a270dc4ef9decf3c4a3461e",
    "version" : 1,
    "locktime" : 3,
    "vin" : [
        {
            "txid" : "c837c82b04df0bac981149fea5c07e2bc855e4d525d63ff9a9b0f4f393f510b1",
            "vout" : 0,
            "scriptSig" : {
                "asm" : "304502207501c32e46cfba0ac5aae64849a34107c2a30291448604d0c207ae7c0a05c65d022100f914d06a0f64331d0b6ba931d62db2257293c199d4541bbb02266cf0fa1272f501 035ecd174d977eecdda204fd52be159469b77399f8f19894a70b72216197525782",
                "hex" : "48304502207501c32e46cfba0ac5aae64849a34107c2a30291448604d0c207ae7c0a05c65d022100f914d06a0f64331d0b6ba931d62db2257293c199d4541bbb02266cf0fa1272f50121035ecd174d977eecdda204fd52be159469b77399f8f19894a70b72216197525782"
            },
            "sequence" : 4294963455
        }
    ],
    "vout" : [
        {
            "value" : 18.00000000,
            "n" : 0,
            "scriptPubKey" : {
                "asm" : "OP_DUP OP_HASH160 be42ebf8ab45f191de4703213a093510b8259591 OP_EQUALVERIFY OP_CHECKSIG",
                "hex" : "76a914be42ebf8ab45f191de4703213a093510b825959188ac",
                "reqSigs" : 1,
                "type" : "pubkeyhash",
                "addresses" : [
                    "mxrxrJnR2XP889vMz2ewVZ97dvgso6DfF6"
                ]
            }
        }
    ],
    "blockhash" : "000000000b5ac111cc15c3b47cc46e877e5b93f250a927a14dddcddf013bfee5",
    "confirmations" : 2493,
    "time" : 1356543924,
    "blocktime" : 1356543924
}

The sequence number is a bit strange because I just replaced an f by a 0 in the hex transaction, but I think it is OK.

I will continue playing and post the results. I might be doing something else wrong.
Peter Todd
Legendary
*
expert
Offline Offline

Activity: 1106
Merit: 1013


View Profile
January 06, 2013, 01:15:49 AM
 #8

  I'm still a bit confused, because right after sending them, I could spend the coins in another transaction. Here is an example transaction:

Code:
    "locktime" : 3,

The reason why you were able to spend that tx is because of this. What you've done is made a transaction that can't be spent in any block before block #3, which was over four years ago.

What did you expect to happen?

jl2012
Legendary
*
Offline Offline

Activity: 1792
Merit: 1010


View Profile
January 06, 2013, 08:06:11 AM
Last edit: January 06, 2013, 12:23:08 PM by jl2012
 #9

Quote
It seems none of them will be able to be redeemed for a long time.

Quote
"locktime" : 3,

obviously you misunderstand the meaning of nlocktime. The value refers to the absolute block height, not a relative one. Your example means "locked after block height = 3", not "locked 3 blocks later"

Donation address: 374iXxS4BuqFHsEwwxUuH3nvJ69Y7Hqur3 (Bitcoin ONLY)
LRDGENPLYrcTRssGoZrsCT1hngaH3BVkM4 (LTC)
PGP: D3CC 1772 8600 5BB8 FF67 3294 C524 2A1A B393 6517
halftimepad
Newbie
*
Offline Offline

Activity: 20
Merit: 0


View Profile
January 06, 2013, 11:56:32 AM
 #10

Quote
The reason why you were able to spend that tx is because of this. What you've done is made a transaction that can't be spent in any block before block #3, which was over four years ago.

What did you expect to happen?


Quote
obviously you misunderstand the meaning of nlocktime. The value refers to the absolute block height, a relative one. Your example means "locked after block height = 3", not "locked 3 blocks later"

Ouch! How embarrassing!

Thank you, that's it!


Peter Todd
Legendary
*
expert
Offline Offline

Activity: 1106
Merit: 1013


View Profile
January 06, 2013, 01:36:43 PM
 #11

Speaking of, here is an exercise for you: why must the locktime be an absolute number? Why can't it be a relative number?

halftimepad
Newbie
*
Offline Offline

Activity: 20
Merit: 0


View Profile
January 06, 2013, 09:58:37 PM
Last edit: January 06, 2013, 11:14:34 PM by halftimepad
 #12

Speaking of, here is an exercise for you: why must the locktime be an absolute number? Why can't it be a relative number?

Uhm... I would think it is because you can never be sure which block will carry your transaction. I guess an absolute number gives you an approximate date. Roughly, you can imagine a block will appear each ten minutes and the transaction will be accepted around the time you include in the timestamp.
halftimepad
Newbie
*
Offline Offline

Activity: 20
Merit: 0


View Profile
January 06, 2013, 11:29:54 PM
 #13

I finally did it!

Testnet3 transaction: 33924d240e571f633ee2ea64ffd917d0c6a9a995b670740e54c5bc954f6f33bd

Thank you all for the help. The standard client shows it alright and works as expected.
Peter Todd
Legendary
*
expert
Offline Offline

Activity: 1106
Merit: 1013


View Profile
January 06, 2013, 11:36:54 PM
 #14

Speaking of, here is an exercise for you: why must the locktime be an absolute number? Why can't it be a relative number?

Uhm... I would think it is because you can never be sure which block will carry your transaction. I guess an absolute number gives you an approximate date. Roughly, you can imagine a block will appear each ten minutes and the transaction will be accepted around the time you include in the timestamp.

That's exactly it. You might fight this post by satoshi on that subject interesting: https://bitcointalk.org/index.php?topic=1786.msg22119#msg22119

Congrats on your tx!

phelix
Legendary
*
Offline Offline

Activity: 1708
Merit: 1000


nmc:id/phelix


View Profile
March 29, 2013, 09:23:15 AM
 #15

Can nLockTime TX be used to flood Mempools?
http://bitcoin.stackexchange.com/questions/8408/can-nlocktime-tx-be-used-to-flood-mempools

Quote from: danny
If the transactions are properly linked to previous valid transactions they eventually get into the blockchain (and out of the mempool) regardless of the nLockTime

lockTime prevents a transaction from getting into blocks. Once it's in a block, it can be spent.

From what I see in the source I think danny is wrong and theymos is right: All tx in a block need to be "final" and a tx is only final if we passed it's nLockTime (blockheight or unixtime).

Can somebody confirm this?

blockchained.com ■ bitcointalk top posts
theymos
Administrator
Legendary
*
Offline Offline

Activity: 3402
Merit: 5638


View Profile
March 29, 2013, 12:20:18 PM
 #16

All tx in a block need to be "final"

Right.

a tx is only final if we passed it's nLockTime (blockheight or unixtime).

A transaction is also final if its sequence number is equal to UINT_MAX, regardless of nLockTime.

1NXYoJ5xU91Jp83XfVMHwwTUyZFK64BoAD
phelix
Legendary
*
Offline Offline

Activity: 1708
Merit: 1000


nmc:id/phelix


View Profile
March 29, 2013, 04:04:23 PM
 #17

All tx in a block need to be "final"

Right.

a tx is only final if we passed it's nLockTime (blockheight or unixtime).

A transaction is also final if its sequence number is equal to UINT_MAX, regardless of nLockTime.

Thanks for explaining. Now I need to think about it some more.  Roll Eyes

blockchained.com ■ bitcointalk top posts
scrubadub
Newbie
*
Offline Offline

Activity: 35
Merit: 0


View Profile
April 24, 2013, 01:38:20 AM
 #18

It seems like there are three ways someone may want to use transactions/locktime

1. Send a transaction with locktime and revoke or change it before the lock time
2. Send a transaction with locktime and be unable to change it, yet the party receiving the transaction can still not spend it until locktime
3. Send a transaction and shortcut the locktime (basically a normal transaction, described below with uint_max)

So reading this thread I understand transactions aren't in blocks until they are final / locktime expires (unless unit_max), but I'm thinking more theoretically for a second on how it should/could work.

So usecase #1 seems covered today, I'm told you can resend transactions without the lock time or with a new version and other miners will confirm this (correct me if I'm wrong)
And usecase #3 is basically a normal transaction without locktime.

The interesting usecase is #2 I think. Here are a few problems I see...

Right now nodes probably wont relay transactions with a future locktime of n days out, forcing the party creating the transaction to resend the transaction closer to the locktime or give the transaction to the receiving party to retransmit. Possible solution to this problem is include the transaction in the blockchain, it would be not be able to be changed but that is the purposes of usecase #2.

Because the transaction is not confirmed until the future locktime, the sending party can create another transaction and mine a block their-selves (or ask someone else to) and reverse a transaction with a future locktime. The only way around this I see is to add future transactions to the blockchain.

So if you did add the transaction to the blockchain then your problem is how do you prevent the receiving party of the transaction from spending the coins before locktime. Though this seems like a easier problem than trying to solve the above two problems. Is it not possible to check the parent transaction of a newly created transaction to make sure it is valid at the time of the new transaction?

Again I (think I) realize how it works today, but I dont think this usecase #2 is covered today (please correct me if i'm wrong). Assuming #2 isn't covered today, would adding future transactions to the blockchain, and verifying the parent transaction's locktime be possible? Or does that break all kinds of other things I'm not thinking about.

Thanks
scrubadub
Newbie
*
Offline Offline

Activity: 35
Merit: 0


View Profile
May 17, 2013, 07:33:47 PM
 #19

Shamelessly bumping for comments on bitcoin supporting three different types of transactions based on locktime (discussed above).

Thoughts?
Mike Hearn
Legendary
*
expert
Offline Offline

Activity: 1526
Merit: 1008


View Profile
May 17, 2013, 09:49:10 PM
 #20

Well, the purpose of nLockTime isn't really to literally lock coins for a particular time, it's intended as part of contract negotiation to allow you to use the memory pool as a kind of race resolver. Whilst you can lock some coins for a long period of time, indeed the risk is that somebody finney attacks you. You can reduce the risk by requiring both parties to sign for the output, for example, but there isn't really a good way to do what you want short of a hard forking rule change. And I don't see any use cases that would justify that.
Pages: [1] 2 3 »  All
  Print  
 
Jump to:  

Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!