diff --git a/erisdb/pipe/transactor.go b/erisdb/pipe/transactor.go
index c406d9c66d775c77bcc54912dbac002f8f8d16cd..23f6a000190ebb8a68c00d27a39f8c8e5d1396ca 100644
--- a/erisdb/pipe/transactor.go
+++ b/erisdb/pipe/transactor.go
@@ -177,12 +177,25 @@ func (this *transactor) TransactAndHold(privKey, address, data []byte, gasLimit,
 	} else {
 		addr = address
 	}
-	wc := make(chan *types.EventDataCall)
+
+	// We want non-blocking on the first event received (but buffer the value),
+	// after which we want to block (and then discard the value - see below)
+	wc := make(chan *types.EventDataCall, 1)
+
 	subId := fmt.Sprintf("%X", rec.TxHash)
 	this.eventEmitter.Subscribe(subId, types.EventStringAccCall(addr), func(evt types.EventData) {
 		event := evt.(types.EventDataCall)
 		if bytes.Equal(event.TxID, rec.TxHash) {
-			wc <- &event
+			//  Beware the contract of go-events subscribe is that we must not be
+			// blocking in an event callback when we try to unsubscribe!
+			// We work around this by using a non-blocking receive.
+			select {
+			// This is a non-blocking send, but since we are using a buffered
+			// channel of size 1 we will always grab our first event even if we
+			// haven't read from the channel at the time we receive the first event.
+			case wc <- &event:
+			default:
+			}
 		}
 	})